Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions googleapiclient/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,14 @@ def execute(self, http=None):
if http is None:
raise ValueError("Missing a valid http object.")

# Special case for OAuth2Credentials-style objects which have not yet been
# refreshed with an initial access_token.
if getattr(http.request, 'credentials', None) is not None:
creds = http.request.credentials
if not getattr(creds, 'access_token', None):
LOGGER.info('Attempting refresh to obtain initial access_token')
creds.refresh(http)

self._execute(http, self._order, self._requests)

# Loop over all the requests and check for 401s. For each 401 request the
Expand Down
28 changes: 28 additions & 0 deletions tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,34 @@ def test_execute_request_body(self):
header = parts[1].splitlines()[1]
self.assertEqual('Content-Type: application/http', header)

def test_execute_initial_refresh_oauth2(self):
batch = BatchHttpRequest()
callbacks = Callbacks()
cred = MockCredentials('Foo')

# Pretend this is a OAuth2Credentials object
cred.access_token = None

http = HttpMockSequence([
({'status': '200',
'content-type': 'multipart/mixed; boundary="batch_foobarbaz"'},
BATCH_SINGLE_RESPONSE),
])

cred.authorize(http)

batch.add(self.request1, callback=callbacks.f)
batch.execute(http=http)

self.assertEqual({'foo': 42}, callbacks.responses['1'])
self.assertIsNone(callbacks.exceptions['1'])

self.assertEqual(1, cred._refreshed)

self.assertEqual(1, cred._authorized)

self.assertEqual(1, cred._applied)

def test_execute_refresh_and_retry_on_401(self):
batch = BatchHttpRequest()
callbacks = Callbacks()
Expand Down