Open
Description
While using the BatchHttpRequest class I found that it did not work behind a firewall. I found this is because even though I was giving it an AuthorizedHttp object that internally wants to handle 401s and refresh the batch is looking for them and calling refresh_credentials which internally does this:
def refresh_credentials(credentials):
# Refresh must use a new http instance, as the one associated with the
# credentials could be a AuthorizedHttp or an oauth2client-decorated
# Http instance which would cause a weird recursive loop of refreshing
# and likely tear a hole in spacetime.
refresh_http = httplib2.Http()
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
request = google_auth_httplib2.Request(refresh_http)
return credentials.refresh(request)
else:
return credentials.refresh(refresh_http)
If this really needs to happen maybe pass through a function that constructs an http client with preferred settings.
Steps to reproduce
- Setup a firewall the requires the use of a proxy
- construct an http client that can use the proxy
- build a compute client and create a batch request with new_batch_request
- see that something like get projects will 401 and auto refresh the token
- see that the batch execution fails
Code example
credentials = Credentials(**gcp_api_credentials)
http = Http(
proxy_info=self._get_callable_proxies(),
ca_certs=verify_ssl or None,
disable_ssl_certificate_validation=not verify_ssl,
)
self.compute = build(
'compute',
'v1',
http=http or self.authorized_http,
)
batch = self.compute.new_batch_http_request(callback=process_response)
for idx, request in requests.items():
batch.add(request, request_id=idx)
batch.execute()
I worked around this by pre-refreshing the token after constructing the credentials