【问题标题】:Google Drive Python API: Uploading Large FilesGoogle Drive Python API:上传大文件
【发布时间】:2018-08-06 05:28:48
【问题描述】:

我正在编写一个函数来使用Python API client 将文件上传到 Google 云端硬盘。它适用于最大 1 MB 的文件,但不适用于 10 MB 的文件。当我尝试上传 10 MB 的文件时,我收到 HTTP 400 错误。任何帮助,将不胜感激。谢谢。

这是我打印错误时的输出:

An error occurred: <HttpError 400 when requesting https://www.googleapis.com/upload/drive/v3/files?alt=json&uploadType=resumable returned "Bad Request">

这是我打印 error.resp 时的输出:

{'server': 'UploadServer', 'status': '400', 'x-guploader-uploadid': '...', 'content-type': 'application/json; charset=UTF-8', 'date': 'Mon, 26 Feb 2018 17:00:12 GMT', 'vary': 'Origin, X-Origin', 'alt-svc': 'hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303338; quic=51303337; quic=51303335,quic=":443"; ma=2592000; v="41,39,38,37,35"', 'content-length': '171'}

我无法解释这个错误。我试过查看Google API Error Guide,但他们的解释对我来说没有意义,因为所有参数都与具有较小文件的请求中的参数相同,这可以工作。

这是我的代码:

def insert_file_only(service, name, description, filename='', parent_id='root', mime_type=GoogleMimeTypes.PDF):
    """ Insert new file.

    Using documentation from Google Python API as a guide:
        https://developers.google.com/api-client-library/python/guide/media_upload

    Args:
        service: Drive API service instance.
        name: Name of the file to create, including the extension.
        description: Description of the file to insert.
        filename: Filename of the file to insert.
        parent_id: Parent folder's ID.
        mime_type: MIME type of the file to insert.
    Returns:
        Inserted file metadata if successful, None otherwise.
    """

    # Set the file meta data
    file_metadata = set_file_metadata(name, description, mime_type, parent_id)

    # Create media with correct chunk size
    if os.stat(filename).st_size <= 256*1024:
        media = MediaFileUpload(filename, mimetype=mime_type, resumable=True)
    else:
        media = MediaFileUpload(filename, mimetype=mime_type, chunksize=256*1024, resumable=True)

    file = None
    status = None
    start_from_beginning = True
    num_temp_errors = 0

    while file is None:
        try:
            if start_from_beginning:
                # Start from beginning
                logger.debug('Starting file upload')
                file = service.files().create(body=file_metadata, media_body=media).execute()
            else:
                # Upload next chunk
                logger.debug('Uploading next chunk')
                status, file = service.files().create(
                    body=file_metadata, media_body=media).next_chunk()
                if status:
                    logger.info('Uploaded {}%'.format(int(100*status.progress())))

        except errors.HttpError as error:
            logger.error('An error occurred: %s' % error)
            logger.error(error.resp)
            if error.resp.status in [404]:
                # Start the upload all over again
                start_from_beginning = True
            elif error.resp.status in [500, 502, 503, 504]:
                # Increment counter on number of temporary errors
                num_temp_errors += 1
                if num_temp_errors >= NUM_TEMP_ERROR_LIMIT:
                    return None
                # Call next chunk again
            else:
                return None

    permissions = assign_permissions(file, service)
    return file

更新
我尝试使用更简单的模式,并听取了@StefanE 的建议。但是,对于超过 1 MB 的文件,我仍然会收到 HTML 400 错误。新代码如下所示:

request = service.files().create(body=file_metadata, media_body=media)
response = None
while response is None:
    status, response = request.next_chunk()
    if status:
        logger.info('Uploaded {}%'.format(int(100*status.progress()))

更新 2
我发现问题是将文件转换为 Google 文档,而不是上传。我正在尝试上传 HTML 文件并将其转换为 Google Doc。这适用于小于 ~2 MB 的文件。当我只上传 HTML 文件而不尝试转换它时,我没有收到上述错误。看起来这与page 的限制相对应。不知道这个上限能不能提高。

【问题讨论】:

    标签: python google-drive-api


    【解决方案1】:

    我发现您的代码存在一些问题。

    首先你有一个while循环来继续file is None,你要做的第一件事就是设置file的值。即它只会循环一次。

    其次,你得到了变量start_from_beginning,但它永远不会在代码中的任何地方设置为 False,语句的 else 部分将永远不会被执行。

    查看 Google 的文档,他们的示例代码看起来更直接:

    media = MediaFileUpload('pig.png', mimetype='image/png', resumable=True)
    request = farm.animals().insert(media_body=media, body={'name': 'Pig'})
    response = None
    while response is None:
      status, response = request.next_chunk()
      if status:
        print "Uploaded %d%%." % int(status.progress() * 100)
    print "Upload Complete!"
    

    在此循环,while response is None 这将是 None 直到完成上传。

    【讨论】:

    • 感谢您的帮助。该文档可能来自较旧的 API。当我用 insert() 替换 create() 时,我得到了一个 AttributeError。如果您查看Google documentation 的底部,您会发现我正在尝试复制的异常处理模式。
    • API 的文档很奇怪。他们使用诸如“插入方法可能允许...”之类的短语,这让我想知道这是否是一个实际的代码示例。
    • 这个 farm.animals().insert 是从哪里来的?
    • @EduardoFernandes 这是文档中的一个示例 - googleapis.github.io/google-api-python-client/docs/epy/…
    猜你喜欢
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多