Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export spreadsheet as text/csv using Drive v3 gives 500 Internal Error

I was trying to export a Google Spreadsheet in csv format using the Google client library for Python:

# OAuth and setups...
req = g['service'].files().export_media(fileId=fileid, mimeType=MIMEType)
fh = io.BytesIO()
downloader = http.MediaIoBaseDownload(fh, req)
# Other file IO handling...

This works for MIMEType: application/pdf, MS Excel, etc.

According to Google's documentation, text/csv is supported. But when I try to make a request, the server gives a 500 Internal Error.

Even using google's Drive API playground, it gives the same error.

Tried:

Like in v2, I added a field:

gid = 0

to the request to specify the worksheet, but then it's a bad request.

like image 642
Anton Qiu Avatar asked Jan 04 '16 22:01

Anton Qiu


2 Answers

This is a known bug in Google's code. https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4289

However, if you manually build your own request, you can download the whole file in bytes (the media management stuff won't work).

With file as the file ID, http as the http object that you've authorized against you can download a file with:

from apiclient.http import HttpRequest
def postproc(*args):
    return args[1]
data = HttpRequest(http=http,
                   postproc=postproc,
                   uri='https://docs.google.com/feeds/download/spreadsheets/Export?key=%s&exportFormat=csv' % file,
                   headers={ }).execute()

data here is a bytes object that contains your CSV. You can open it something like:

import io
lines = io.TextIOWrapper(io.BytesIO(data), encoding='utf-8', errors='replace')
for line in lines:
    #Do whatever
like image 117
Joseph Hackman Avatar answered Oct 23 '22 04:10

Joseph Hackman


You just need to implement an Exponential Backoff.

Looking at this documentation of ExponentialBackOffPolicy.

The idea is that the servers are only temporarily unavailable, and they should not be overwhelmed when they are trying to get back up.

The default implementation requires back off for 500 and 503 status codes. Subclasses may override if different status codes are required.

Here is an snippet of an implementation of Exponential Backoff from the first link:

ExponentialBackOff backoff = ExponentialBackOff.builder()
.setInitialIntervalMillis(500)
.setMaxElapsedTimeMillis(900000)
.setMaxIntervalMillis(6000)
.setMultiplier(1.5)
.setRandomizationFactor(0.5)
.build();
request.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff));

You may want to look at this documentation for the summary of the ExponentialBackoff implementation.

like image 23
gerardnimo Avatar answered Oct 23 '22 05:10

gerardnimo