xiaowl
xiaowl

Reputation: 5207

Get 400 error when try to upload a image file to a collection

I want to write a script to upload my photos to Google Drive. After couples of hours of digging into Google Document List API. I choose gdata-python-client 2.0.17(latest) to build my script. Everything works well, except that I cannot upload a file to a collection. Here is the exception.

Traceback (most recent call last):
  File "./upload.py", line 27, in 
    upload(sys.argv[1])
  File "./upload.py", line 22, in upload
    client.create_resource(p, collection=f, media=ms)
  File "/usr/local/lib/python2.7/dist-packages/gdata/docs/client.py", line 300, in create_resource
    return uploader.upload_file(create_uri, entry, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/gdata/client.py", line 1090, in upload_file
    start_byte, self.file_handle.read(self.chunk_size))
  File "/usr/local/lib/python2.7/dist-packages/gdata/client.py", line 1048, in upload_chunk
    raise error
gdata.client.RequestError: Server responded with: 400, <errors xmlns='http://schemas.google.com/g/2005'><error><domain>GData</domain><code>InvalidEntryException</code><internalReason>We're sorry, a server error occurred. Please try again.</internalReason></error></errors>

After hacking into the source code of gdata, I print some info for debugging.

>
Range: bytes 0-524287/729223
PUT TO: https://docs.google.com/feeds/upload/create-session/default/private/full/folder%3A0B96cfHivZx6ddGFwYXVCbzc4U3M/contents?upload_id=AEnB2UqnYRFTOyCCIGIESUIctWg6hvQIHY4JRMnL-CUQhHii3RGMFWZ12a7lXWd1hgOChd1Vqlr8d-BmvyfmhFhzhYK9Vnw4Xw
>
Range: bytes 524288-729222/729223
PUT TO: https://docs.google.com/feeds/upload/create-session/default/private/full/folder%3A0B96cfHivZx6ddGFwYXVCbzc4U3M/contents?upload_id=AEnB2UqnYRFTOyCCIGIESUIctWg6hvQIHY4JRMnL-CUQhHii3RGMFWZ12a7lXWd1hgOChd1Vqlr8d-BmvyfmhFhzhYK9Vnw4Xw

The exception raised when PUT the last part of file.

Upvotes: 3

Views: 1527

Answers (1)

Alain
Alain

Reputation: 6034

I would advise you to try the new Google Drive API v2 that makes it much easier with better support for media upload: https://developers.google.com/drive/v2/reference/files/insert

Once you get an authorized service instance, you can simply insert a new file like so:

from apiclient import errors
from apiclient.http import MediaFileUpload
# ...

def insert_file(service, title, description, parent_id, mime_type, filename):
  """Insert new file.

  Args:
    service: Drive API service instance.
    title: Title of the file to insert, including the extension.
    description: Description of the file to insert.
    parent_id: Parent folder's ID.
    mime_type: MIME type of the file to insert.
    filename: Filename of the file to insert.
  Returns:
    Inserted file metadata if successful, None otherwise.
  """
  media_body = MediaFileUpload(filename, mimetype=mime_type, resumable=True)
  body = {
    'title': title,
    'description': description,
    'mimeType': mime_type
  }
  # Set the parent folder.
  if parent_id:
    body['parents'] = [{'id': parent_id}]

  try:
    file = service.files().insert(
        body=body,
        media_body=media_body).execute()

    return file
  except errors.HttpError, error:
    print 'An error occured: %s' % error
    return None

Upvotes: 1

Related Questions