用于将大文件上传到没有Google Driver UI的Google云端硬盘的POST消息

时间:2012-07-11 20:38:33

标签: python google-app-engine google-drive-api

我的理解是,要使用API​​的第2版从我自己的应用上传大文件到Google云端硬盘,我应该发送如下信息。不幸的是,我不知道如何使用Python实现多部分消息的这种格式。有没有人有示例Python代码可以让我朝着正确的方向前进?

谢谢, 克里斯


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>--

2 个答案:

答案 0 :(得分:4)

Google Drive API的参考指南包含多种语言的代码段,包括适用于所有API端点的Python。

对于您的用例,drive.files.insert端点有答案:

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

答案 1 :(得分:2)

我在其他地方找到了答案,这个Python代码会生成问题中显示的消息。

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)