17
17
import json
18
18
import pathlib
19
19
20
- import google .auth
21
- from google .auth .transport import requests
22
- from google .oauth2 import credentials
20
+ from typing import (
21
+ Type ,
22
+ List
23
+ )
24
+
25
+ import google .auth # type: ignore
26
+ from google .auth import default
27
+ from google .auth ._default_async import default_async # type: ignore
28
+ from google .auth .transport import requests # type: ignore
29
+ from google .auth .transport import _aiohttp_requests as aiohttp_requests
30
+ from google .oauth2 import credentials # type: ignore
31
+ from google .oauth2 import _credentials_async as credentials_async
23
32
from google .oauth2 import service_account
33
+ from google .oauth2 import _service_account_async as service_account_async
24
34
25
35
26
- _request = requests .Request ()
27
- _scopes = [
36
+ _request : requests .Request = requests .Request ()
37
+ _request_async : aiohttp_requests .Request = aiohttp_requests .Request ()
38
+ _scopes : List [str ] = [
28
39
'https://www.googleapis.com/auth/cloud-platform' ,
29
40
'https://www.googleapis.com/auth/datastore' ,
30
41
'https://www.googleapis.com/auth/devstorage.read_write' ,
33
44
'https://www.googleapis.com/auth/userinfo.email'
34
45
]
35
46
36
- AccessTokenInfo = collections .namedtuple ('AccessTokenInfo' , ['access_token' , 'expiry' ])
47
+ AccessTokenInfo : Type [ tuple ] = collections .namedtuple ('AccessTokenInfo' , ['access_token' , 'expiry' ])
37
48
"""Data included in an OAuth2 access token.
38
49
39
50
Contains the access token string and the expiry time. The expirty time is exposed as a
44
55
class Base :
45
56
"""Provides OAuth2 access tokens for accessing Firebase services."""
46
57
47
- def get_access_token (self ):
48
- """Fetches a Google OAuth2 access token using this credential instance.
58
+ def get_access_token (self ) -> tuple :
59
+ """Fetches a Google OAuth2 access token using the synchronous credential instance.
49
60
50
61
Returns:
51
62
AccessTokenInfo: An access token obtained using the credential.
@@ -54,8 +65,22 @@ def get_access_token(self):
54
65
google_cred .refresh (_request )
55
66
return AccessTokenInfo (google_cred .token , google_cred .expiry )
56
67
68
+ async def get_access_token_async (self ) -> tuple :
69
+ """Fetches a Google OAuth2 access token using the asynchronous credential instance.
70
+
71
+ Returns:
72
+ AccessTokenInfo: An access token obtained using the credential.
73
+ """
74
+ google_cred = self .get_credential_async ()
75
+ await google_cred .refresh (_request_async )
76
+ return AccessTokenInfo (google_cred .token , google_cred .expiry )
77
+
57
78
def get_credential (self ):
58
- """Returns the Google credential instance used for authentication."""
79
+ """Returns the Google synchronous credential instance used for authentication."""
80
+ raise NotImplementedError
81
+
82
+ def get_credential_async (self ):
83
+ """Returns the Google asynchronous credential instance used for authentication."""
59
84
raise NotImplementedError
60
85
61
86
@@ -64,8 +89,8 @@ class Certificate(Base):
64
89
65
90
_CREDENTIAL_TYPE = 'service_account'
66
91
67
- def __init__ (self , cert ) :
68
- """Initializes a credential from a Google service account certificate.
92
+ def __init__ (self , cert : str ) -> None :
93
+ """Initializes credentials from a Google service account certificate.
69
94
70
95
Service account certificates can be downloaded as JSON files from the Firebase console.
71
96
To instantiate a credential from a certificate file, either specify the file path or a
@@ -95,44 +120,55 @@ def __init__(self, cert):
95
120
try :
96
121
self ._g_credential = service_account .Credentials .from_service_account_info (
97
122
json_data , scopes = _scopes )
123
+ self ._g_credential_async = service_account_async .Credentials .from_service_account_info (
124
+ json_data , scopes = _scopes )
98
125
except ValueError as error :
99
126
raise ValueError ('Failed to initialize a certificate credential. '
100
127
'Caused by: "{0}"' .format (error ))
101
128
102
129
@property
103
- def project_id (self ):
130
+ def project_id (self ) -> str :
104
131
return self ._g_credential .project_id
105
132
106
133
@property
107
- def signer (self ):
134
+ def signer (self ) -> google . auth . crypt . Signer :
108
135
return self ._g_credential .signer
109
136
110
137
@property
111
- def service_account_email (self ):
138
+ def service_account_email (self ) -> str :
112
139
return self ._g_credential .service_account_email
113
140
114
- def get_credential (self ):
115
- """Returns the underlying Google credential.
141
+ def get_credential (self ) -> service_account . Credentials :
142
+ """Returns the underlying Google synchronous credential.
116
143
117
144
Returns:
118
- google.auth.credentials.Credentials: A Google Auth credential instance."""
145
+ google.auth.credentials.Credentials: A Google Auth synchronous credential instance."""
119
146
return self ._g_credential
120
147
148
+ def get_credential_async (self ) -> service_account_async .Credentials :
149
+ """Returns the underlying Google asynchronous credential.
150
+
151
+ Returns:
152
+ google.auth._credentials_async.Credentials: A Google Auth asynchronous credential
153
+ instance."""
154
+ return self ._g_credential_async
121
155
122
156
class ApplicationDefault (Base ):
123
157
"""A Google Application Default credential."""
124
158
125
- def __init__ (self ):
159
+ def __init__ (self ) -> None :
126
160
"""Creates an instance that will use Application Default credentials.
127
161
128
- The credentials will be lazily initialized when get_credential() or
129
- project_id() is called. See those methods for possible errors raised.
162
+ The credentials will be lazily initialized when ``get_credential()``,
163
+ ``get_credential_async()`` or ``project_id()`` is called. See those methods for possible
164
+ errors raised.
130
165
"""
131
166
super (ApplicationDefault , self ).__init__ ()
132
167
self ._g_credential = None # Will be lazily-loaded via _load_credential().
168
+ self ._g_credential_async = None # Will be lazily-loaded via _load_credential_async().
133
169
134
- def get_credential (self ):
135
- """Returns the underlying Google credential.
170
+ def get_credential (self ) -> credentials . Credentials :
171
+ """Returns the underlying Google synchronous credential.
136
172
137
173
Raises:
138
174
google.auth.exceptions.DefaultCredentialsError: If Application Default
@@ -142,9 +178,20 @@ def get_credential(self):
142
178
self ._load_credential ()
143
179
return self ._g_credential
144
180
181
+ def get_credential_async (self ) -> credentials_async .Credentials :
182
+ """Returns the underlying Google asynchronous credential.
183
+
184
+ Raises:
185
+ google.auth.exceptions.DefaultCredentialsError: If Application Default
186
+ credentials cannot be initialized in the current environment.
187
+ Returns:
188
+ google.auth._credentials_async.Credentials: A Google Auth credential instance."""
189
+ self ._load_credential_async ()
190
+ return self ._g_credential_async
191
+
145
192
@property
146
- def project_id (self ):
147
- """Returns the project_id from the underlying Google credential .
193
+ def project_id (self ) -> str :
194
+ """Returns the project_id from the underlying Google credentials .
148
195
149
196
Raises:
150
197
google.auth.exceptions.DefaultCredentialsError: If Application Default
@@ -154,21 +201,25 @@ def project_id(self):
154
201
self ._load_credential ()
155
202
return self ._project_id
156
203
157
- def _load_credential (self ):
204
+ def _load_credential (self ) -> None :
158
205
if not self ._g_credential :
159
- self ._g_credential , self ._project_id = google .auth .default (scopes = _scopes )
206
+ self ._g_credential , self ._project_id = default (scopes = _scopes )
207
+
208
+ def _load_credential_async (self ) -> None :
209
+ if not self ._g_credential_async :
210
+ self ._g_credential_async , self ._project_id = default_async (scopes = _scopes )
160
211
161
212
class RefreshToken (Base ):
162
- """A credential initialized from an existing refresh token."""
213
+ """Credentials initialized from an existing refresh token."""
163
214
164
215
_CREDENTIAL_TYPE = 'authorized_user'
165
216
166
- def __init__ (self , refresh_token ) :
167
- """Initializes a credential from a refresh token JSON file.
217
+ def __init__ (self , refresh_token : str ) -> None :
218
+ """Initializes credentials from a refresh token JSON file.
168
219
169
- The JSON must consist of client_id, client_secret and refresh_token fields. Refresh
170
- token files are typically created and managed by the gcloud SDK. To instantiate
171
- a credential from a refresh token file, either specify the file path or a dict
220
+ The JSON must consist of `` client_id``, `` client_secret`` and `` refresh_token`` fields.
221
+ Refresh token files are typically created and managed by the gcloud SDK. To instantiate
222
+ credentials from a refresh token file, either specify the file path or a dict
172
223
representing the parsed contents of the file.
173
224
174
225
Args:
@@ -194,28 +245,40 @@ def __init__(self, refresh_token):
194
245
raise ValueError ('Invalid refresh token configuration. JSON must contain a '
195
246
'"type" field set to "{0}".' .format (self ._CREDENTIAL_TYPE ))
196
247
self ._g_credential = credentials .Credentials .from_authorized_user_info (json_data , _scopes )
248
+ self ._g_credential_async = credentials_async .Credentials .from_authorized_user_info (
249
+ json_data ,
250
+ _scopes
251
+ )
197
252
198
253
@property
199
- def client_id (self ):
254
+ def client_id (self ) -> str :
200
255
return self ._g_credential .client_id
201
256
202
257
@property
203
- def client_secret (self ):
258
+ def client_secret (self ) -> str :
204
259
return self ._g_credential .client_secret
205
260
206
261
@property
207
- def refresh_token (self ):
262
+ def refresh_token (self ) -> str :
208
263
return self ._g_credential .refresh_token
209
264
210
- def get_credential (self ):
211
- """Returns the underlying Google credential.
265
+ def get_credential (self ) -> credentials . Credentials :
266
+ """Returns the underlying Google synchronous credential.
212
267
213
268
Returns:
214
- google.auth.credentials.Credentials: A Google Auth credential instance."""
269
+ google.auth.credentials.Credentials: A Google Auth synchronous credential instance."""
215
270
return self ._g_credential
216
271
272
+ def get_credential_async (self ) -> credentials_async .Credentials :
273
+ """Returns the underlying Google asynchronous credential.
274
+
275
+ Returns:
276
+ google.auth._credentials_async.Credentials: A Google Auth asynchronous credential
277
+ instance."""
278
+ return self ._g_credential_async
279
+
217
280
218
- def _is_file_path (path ):
281
+ def _is_file_path (path ) -> bool :
219
282
try :
220
283
pathlib .Path (path )
221
284
return True
0 commit comments