无法使用python

时间:2018-02-18 10:39:52

标签: python python-2.7 google-api google-drive-api google-drive-realtime-api

我正在尝试使用以下代码

通过Google API将文件上传到Google云端硬盘
import httplib2
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

SCOPES =['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive.appdata', 'https://www.googleapis.com/auth/drive.apps.readonly']
store = file.Storage('scope.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store, flags) if flags else tools.run(flow, store)
    DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))
else:
    credentials = creds
    http = credentials.authorize(httplib2.Http())
    DRIVE = discovery.build('drive', 'v3', http=http)

FILES = (
    ('/home/vkm/mayur/Demo_Google_API.zip', 'application/vmd.google-apps.document'),
)

for filename, mimeType in FILES:
    metadata = {'name': filename}
    if mimeType:
        metadata['mimeType'] = mimeType
    res = DRIVE.files().create(body=metadata, media_body=filename).execute()
    if res:
        print('Uploaded "%s" (%s)' % (filename, res['mimeType']))

我能够上传小文件,但是当我尝试使用8GB的文件时,它正在给MemorryErro。请找到我收到的错误消息。

Traceback (most recent call last):
  File "demo.py", line 46, in <module>
    res = DRIVE.files().create(body=metadata, media_body=filename).execute()
  File "/usr/local/lib/python2.7/dist-packages/googleapiclient/discovery.py", line 853, in method
    payload = media_upload.getbytes(0, media_upload.size())
  File "/usr/local/lib/python2.7/dist-packages/googleapiclient/http.py", line 482, in getbytes
    return self._fd.read(length)
MemoryError

2 个答案:

答案 0 :(得分:3)

Vikram's commentmhawke's answer中发现了一个问题:next_chunk需要在返回值上调用:

request = DRIVE.files().create(body=metadata, media_body=media)

不在request.execute()的返回值。

以下是我验证为我的Google云端硬盘帐户处理最多10MB文件的Python代码片段:

# Upload some file that just happens to be binary (we
# don't care about metadata, just upload it without
# translation):
the_file_to_upload = 'some_binary_file'
metadata = {'name': the_file_to_upload}
# Note the chunksize restrictions given in
# https://developers.google.com/api-client-library/python/guide/media_upload
media = MediaFileUpload(the_file_to_upload,
                        chunksize=1024 * 1024,
                        # Not sure whether or not this mimetypes is necessary:
                        mimetype='text/plain',
                        resumable=True)
request = drive_service.files().create(body=metadata, media_body=media)
response = None
while response is None:
    status, response = request.next_chunk()
    if status:
        print("Uploaded %d%%." % int(status.progress() * 100))
print("Upload of {} is complete.".format(the_file_to_upload))

以下是一段Python代码,可以下载相同的文件,但会下载到另一个文件,这样我就可以使用sha1sum来验证Google云端硬盘是否已经更改进出。

# Verify downloading works without translation:
request = drive_service.files().get_media(fileId=response['id'])
# Use io.FileIO. Refer to:
# https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.MediaIoBaseDownload-class.html
out_filename = the_file_to_upload + ".out"
fh = io.FileIO(out_filename, mode='wb')
downloader = MediaIoBaseDownload(fh, request, chunksize=1024 * 1024)
done = False
while done is False:
    status, done = downloader.next_chunk()
    if status:
        print("Download %d%%." % int(status.progress() * 100))
print("Download Complete!")

答案 1 :(得分:2)

您可以使用resumable media upload上传文件。这将以块的形式发送文件,并且不应该最大化你的内存,我认为这是因为你的客户端试图立即发送整个文件。

要执行此操作,您需要将MediaFileUpload对象传递到create()标记设置为resumable的{​​{1}}方法。您也可以选择设置True

chunksize

如果需要,请尝试缩小metadata = {'name': filename} media = MediaFileUpload(filename, mimetype=mimetype, resumable=True) request = DRIVE.files().create(body=metadata, media_body=media) response = None while response is None: status, response = request.next_chunk() if status: print "Uploaded %d%%." % int(status.progress() * 100) print "Upload Complete!"