谷歌驱动器python api:export永远不会完成.

摘要:

我有一个问题,有时python的google-drive-sdk没有检测到导出文档的结尾.它似乎认为谷歌文件是无限大小.

我遵循的背景,源代码和教程:

我正在开发自己的基于python的google-drive备份脚本(一个带有良好CLI界面的浏览器). git link for source code

它仍在制作中,目前只能找到新文件并下载它们(使用’pull’命令).

要执行最重要的google-drive命令,我按照官方的google驱动器api教程下载媒体. here

什么有效:

当文档或文件是非google-docs文档时,文件会正确下载.但是,当我尝试“导出”文件时.我看到我需要使用不同的mimeType.我有一本字典.

例如:我在导出文档时将application / vnd.google-apps.document映射到application / vnd.openxmlformats-officedocument.wordprocessingml.document.

从谷歌驱动器下载谷歌文档文件时,这似乎工作正常.我的意思是:我的while循环具有代码状态,done = downloader.next_chunk()将最终设置为true并且下载完成.

什么行不通:

但是,在某些文件中,done标志永远不会变为true,脚本将永远下载.这最终达到几Gb.也许我正在寻找错误的标志,表示文件在导出时已完成.我很惊讶谷歌驱动器永远不会抛出错误.有人知道是什么原因引起的吗?

当前状态

目前我在我的代码中禁用了谷歌文档导出功能.

当我使用像“drive by rakyll”这样的脚本(至少是我的版本)时,只需添加一个指向在线副本的链接.我真的想做一个正确的导出,以便我的离线系统可以维护驱动器上所有内容的完整备份.

附:为了其他人找到这个页面,可以使用“你应该使用这个服务而不是api”.我知道还有其他服务,但我真的希望探索与我自己的其他系统集成的drive-api功能.

最佳答案 好.我在这里找到了伪解决方案.

问题是Google API从不返回Content-Length,响应在Chunks中完成.但是,返回的块是错误的,或者Python API无法正确处理它.

我做的是,获取MediaIoBaseDownload from here的代码

我离开了所有,但改变了这一部分:

if 'content-range' in resp:
    content_range = resp['content-range']
    length = content_range.rsplit('/', 1)[1]
    self._total_size = int(length)
elif 'content-length' in resp:
    self._total_size = int(resp['content-length'])
else:
    # PSEUDO BUG FIX: No content-length, no chunk info, cut the response here.
    self._total_size = self._progress 

最后的其他是我添加的内容.我还通过设置DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024来更改默认块大小.此外,您还必须从该文件中复制一些导入,包括googleapiclient.http import _retry_request,_should_retry_response中的一个导入.

当然这不是一个解决方案,它只是说“如果我不理解响应,那就停止它”.这可能会使一些导出无效,但至少它不会杀死服务器.直到我们找到一个好的解决方案.

更新:

这里已经报道了Bug:https://github.com/google/google-api-python-client/issues/15

截至2017年1月,唯一的解决方法是不使用MediaIoBaseDownload并改为执行此操作(不适合大文件):

req = service.files().export(fileId=file_id, mimeType=mimeType)
resp = req.execute(http=http)
点赞