Google-api-python-client: Timeout option for HttpRequest

Created on 20 Feb 2018  路  7Comments  路  Source: googleapis/google-api-python-client

Hi,
I wanted to use the android publisher API, to automatically upload my app.
So what I am doing:

    from googleapiclient import discovery
    ...
    self._service = discovery.build('androidpublisher', 'v2', credentials=scoped_credentials)
    ....
    apk_request = self._service.edits().apks().upload(
            editId=edit_id,
            packageName=config.target_id,
            media_body=f'{config.target_path}{config.target_name}'
        )

When I call execute() on the apk_request, that request results in an socket.timeout, because of the 6 second, default timeout.

Sadly the HTTPRequest constructor does not have some **kwargs for the wrapped httplib2-object so I could pass down timeout=XXX.

Workaround:

    apk_request.http.http.timeout = XXX  # ehw.
    apk_request.execute()
triage me

Most helpful comment

Results for this issue are surprisingly sparse on google! Here's how I made this work (for uploading large files to google drive):

import socket
from apiclient import discovery

socket.setdefaulttimeout(300) # 5 minutes

service = discovery.build('drive', 'v3', credentials=...)
...

I did originally try experimenting with setting the socket default timeout value in an interactive repl and then importing a custom google drive wrapper around the service object, which did not seem to affect the default timeout, for what it's worth. Hope this helps.

All 7 comments

You should be able to set the global socket timeout.

a working example of how setting the global socket timeout would solve this issue would be helpful. will update this issue if i find one.

Results for this issue are surprisingly sparse on google! Here's how I made this work (for uploading large files to google drive):

import socket
from apiclient import discovery

socket.setdefaulttimeout(300) # 5 minutes

service = discovery.build('drive', 'v3', credentials=...)
...

I did originally try experimenting with setting the socket default timeout value in an interactive repl and then importing a custom google drive wrapper around the service object, which did not seem to affect the default timeout, for what it's worth. Hope this helps.

Results for this issue are surprisingly sparse on google! Here's how I made this work (for uploading large files to google drive):

import socket
from apiclient import discovery

socket.setdefaulttimeout(300) # 5 minutes

service = discovery.build('drive', 'v3', credentials=...)
...

I did originally try experimenting with setting the socket default timeout value in an interactive repl and then importing a custom google drive wrapper around the service object, which did _not_ seem to affect the default timeout, for what it's worth. Hope this helps.

I have same problem to use google sheets api. Although I can ping www.google.com and access google website ( by shadowsocks since I am in China), the result of ping www.googleapis.com is request time out.

I think that is the reason why pygsheets and gspread raise socket.time out error as in issue.

I am wondering is there any restriction to access googleapis.com behind network proxy?

Thank you so much @ryantuck! Linking this issue since google kept taking me there instead of here: https://github.com/googleapis/google-api-python-client/issues/632

Is there an alternative way to set the timeout more locally? I see that this library relies on httplib2 which provides a mechanism for providing a timeout. This class, which is used in the quickstart for authentication also provides a timeout parameter: https://google-auth.readthedocs.io/en/latest/reference/google.auth.transport.requests.html

I find this pretty important since some operations with very large spreadsheets require a very large timeout. I would prefer to set this on the individual requests I know will be slow.

+1. It will be very helpful to be able to set per-request timeout. We work with a service which has some long running methods. We'd like to set longer timeout for these methods only.

@AlJohri @jqll -- I'm not sure if there is a better way to do this, but I was also looking for a way to more locally set a timeout without altering the timeout behavior of all sockets and came up with the following:

from google.oauth2 import service_account
from googleapiclient.discovery import build
import google_auth_httplib2
import httplib2

scopes = []  # change as necessary
credentials = service_account.Credentials.from_service_account_file(
        service_account_file, scopes=scopes)

http = httplib2.Http(timeout=5)
authed_http = google_auth_httplib2.AuthorizedHttp(credentials, http=http)

service = build('calendar', 'v3', http=authed_http)

# assume calendar_id, timeMin, timeMax are initialized properly
req = service.events().list(calendarId=calendar_id, timeMin=timeMin, timeMax=timeMax,
                                        singleEvents=True,
                                        orderBy='startTime')

res = req.execute()
...

If I set timeout to something small like 0.1, then when I execute on a request built from the service, it raises timeout: The read operation timed out. You can also check that req.http.http.timeout has the correct value set.

Was this page helpful?
0 / 5 - 0 ratings