google-api-python-client icon indicating copy to clipboard operation
google-api-python-client copied to clipboard

refresh_credentials constructs new Http object without custom args

Open mattmorganpdx opened this issue 4 years ago • 2 comments

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

  1. Setup a firewall the requires the use of a proxy
  2. construct an http client that can use the proxy
  3. build a compute client and create a batch request with new_batch_request
  4. see that something like get projects will 401 and auto refresh the token
  5. 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

mattmorganpdx avatar Nov 30 '21 23:11 mattmorganpdx

Hi @mattmorganpdx ,

Thank you for reporting this issue. In case you have an interest in putting together a solution, PRs are welcome!

parthea avatar Dec 01 '21 10:12 parthea