Reputation: 543
My understanding is that to upload a large file to Google Drive from my own app using version 2 of the API, I should be sending a message like below. Unfortunately, I do not know how to achieve this format for the multipart message using Python. Does anyone have example Python code that could get me going in the right direction?
Thanks, Chris
POST /upload/drive/v2/files?uploadType=multipart
Authorization: Bearer <Access token>
Content-Length: <length>
Content-Type: multipart/related; boundary="<a base64 encoded guid>"
--<a base64 encoded guid>
Content-Type: application/json
{"title": "test.jpg", "mimeType":"image/jpeg", "parents":[]}
--<a base64 encoded guid>
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
<base64 encoded binary data>
--<a base64 encoded guid>--
Upvotes: 1
Views: 1572
Reputation: 543
I found answer elsewhere, this Python code produces the message shown in the question.
url = 'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart'
boundary = base64.b64encode(uuid.uuid4().bytes)
parts = []
parts.append('--' + boundary)
parts.append('Content-Type: application/json')
parts.append('')
parts.append(json.dumps({
'title': name,
'mimeType': 'image/jpeg',
'parents': [{
'kind': 'drive#file',
'id': folderId
}] if folderId else []
}))
parts.append('--' + boundary)
parts.append('Content-Type: image/jpeg')
parts.append('Content-Transfer-Encoding: base64')
parts.append('')
parts.append(base64.b64encode(content))
parts.append('--' + boundary + '--')
parts.append('')
body = '\r\n'.join(parts)
headers = {
'Content-Type': 'multipart/related; boundary="%s"' % boundary,
'Content-Length': str(len(body)),
'Authorization': 'Bearer %s' % access_token
}
response = urlfetch.fetch(url, payload=body, method='POST', headers=headers)
assert response.status_code == 200, '%s - %s' % (response.status_code, response.content)
r = json.loads(response.content)
Upvotes: 2
Reputation: 6034
The Google Drive API's reference guide contains code snippet in many languages including Python for all of the API endpoints.
For your use-case, the drive.files.insert endpoint has the answer:
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: 4