当前位置: 首页 > 面试题库 >

2小时后Google Drive Python API可恢复上传错误401

傅博容
2023-03-14
问题内容

首先,很抱歉,这是一个太愚蠢的问题……这是我第一次尝试使用此脚本中涉及的任何技术(Python,驱动器api,oauth
2.0等)。我发誓我一直在搜索并尝试这个问题大约一个星期,然后再发布问题。呵呵呵

我正在尝试使用google-api-python-client上传仅在终端机Linux
Debian上的大文件(3.5GiB)。我已经成功上传了小文件,但是当我尝试上传大文件时,上传开始后出现HTTP
401错误(未经授权)后,停止了大约1〜2小时。我一直在寻找如何获取新的访问令牌,但收效甚微。

到目前为止,这是我的( 更新的 )代码:

#!/usr/bin/python

import httplib2
import pprint
import time

from apiclient.discovery import build
from apiclient.http import MediaFileUpload
from apiclient import errors
from oauth2client.client import OAuth2WebServerFlow

# Copy your credentials from the APIs Console
CLIENT_ID = 'myclientid'
CLIENT_SECRET = 'myclientsecret'

# Check https://developers.google.com/drive/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'

# Redirect URI for installed apps
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'

# Run through the OAuth flow and retrieve credentials
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)

# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)

drive_service = build('drive', 'v2', http=http)

# Insert a file
media_body = MediaFileUpload('bigfile.zip', mimetype='application/octet-stream', chunksize=1024*256, resumable=True)
body = {
    'title': 'bigfile.zip',
    'description': 'Big File',
    'mimeType': 'application/octet-stream'
}

retries = 0
request = drive_service.files().insert(body=body, media_body=media_body)
response = None
while response is None:
    try:
            print http.request.credentials.access_token
            status, response = request.next_chunk()
            if status:
                    print "Uploaded %.2f%%" % (status.progress() * 100)
                    retries = 0
    except errors.HttpError, e:
            if e.resp.status == 404:
                    print "Error 404! Aborting."
                    exit()
            else:   
                    if retries > 10:
                            print "Retries limit exceeded! Aborting."
                            exit()
                    else:   
                            retries += 1
                            time.sleep(2**retries)
                            print "Error (%d)... retrying." % e.resp.status
                            continue
print "Upload Complete!"

经过一番挖掘,我发现授权的http对象在收到401之后会自动刷新访问令牌。尽管它确实在更改访问令牌,但仍没有按预期继续上传…请参见以下输出:

ya29.AHES6ZTo_-0oDqwn3JnU2uCR2bRjpRGP0CSQSMHGr6KvgEE
Uploaded 2.28%
ya29.AHES6ZTo_-0oDqwn3JnU2uCR2bRjpRGP0CSQSMHGr6KvgEE
Uploaded 2.29%
ya29.AHES6ZTo_-0oDqwn3JnU2uCR2bRjpRGP0CSQSMHGr6KvgEE
Uploaded 2.29%
ya29.AHES6ZTo_-0oDqwn3JnU2uCR2bRjpRGP0CSQSMHGr6KvgEE
Uploaded 2.30%
ya29.AHES6ZTo_-0oDqwn3JnU2uCR2bRjpRGP0CSQSMHGr6KvgEE
Error (401)... retrying.
ya29.AHES6ZQqp3_qbWsTk4yVDdHnlwc_7GvPZiFIReDnhIIiHao
Error (401)... retrying.
ya29.AHES6ZSqx90ZOUKqDEP4AAfWCVgXZYT2vJAiLwKDRu87JOs
Error (401)... retrying.
ya29.AHES6ZTp0RZ6U5K5UdDom0gq3XHnyVS-2sVU9hILOrG4o3Y
Error (401)... retrying.
ya29.AHES6ZSR-IOiwJ_p_Dm-OnCanVIVhCZLs7H_pYLMGIap8W0
Error (401)... retrying.
ya29.AHES6ZRnmM-YIZj4S8gvYBgC1M8oYy4Hv5VlcwRqgnZCOCE
Error (401)... retrying.
ya29.AHES6ZSF7Q7C3WQYuPAWrxvqbTRsipaVKhv_TfrD_gef1DE
Error (401)... retrying.
ya29.AHES6ZTsGzwIIprpPhCrqmoS3UkPsRzst5YHqL-zXJmz6Ak
Error (401)... retrying.
ya29.AHES6ZSS_1ZBiQJvZG_7t5uW3alsy1piGe4-u2YDnwycVrI
Error (401)... retrying.
ya29.AHES6ZTLFbBS8mSFWQ9zK8cgbX8RPeLghPxkfiKY54hBB-0
Error (401)... retrying.
ya29.AHES6ZQBeMWY50z6fWXvaCcd5_AJr_AYOuL2aiNKpK-mmyU
Error (401)... retrying.
ya29.AHES6ZTs2mYYSEyOqI_Ms4itKDx36t39Oc5RNZHkV4Dq49c
Retries limit exceeded! Aborting.

我正在使用安装了Python 2.5.2的debian lenny,并在大约一周前通过pip install安装了ssl和google-api-
python-client。

在此先感谢您的帮助。

编辑: 显然,问题不在于api。我尝试了与上面相同的代码,但是有两个小文件,它们之间有1h(system.sleep())。输出为:

ya29.AHES6ZRUssiLfuhqCP9Cu7C7LuhRV2rYzPldU27wiMJZWb8
Uploaded 66.89%
ya29.AHES6ZRUssiLfuhqCP9Cu7C7LuhRV2rYzPldU27wiMJZWb8
Upload 1 Complete!
ya29.AHES6ZRUssiLfuhqCP9Cu7C7LuhRV2rYzPldU27wiMJZWb8
Uploaded 57.62%
ya29.AHES6ZQd3o1ciwXpNFImH3CK0-dJAtQba_oeIO9DDbIq154
Upload 2 Complete!

对于第二次上传,成功使用了新的访问令牌。那么,可恢复会话可能会在一段时间后到期,或者仅对特定的访问令牌有效吗?


问题答案:

我在google-api-python-client项目上提出了一个问题,据来自Google的Joe Gregorio称,问题出在后端:

“这是后端的问题,而不是API或代码的问题。据推断,如果上载时间过长,access_token会过期,此时无法继续进行可恢复的上载。立即修复此问题,一旦在服务器端修复此问题,我将更新此错误。”



 类似资料:
  • 有人能告诉我如何在dropwizard 1.2.6中实现可恢复的文件上传吗?因此,如果用户试图上传一个大文件(4-5 GB),如果出现网络故障或浏览器错误关闭,那么用户将能够从中断的地方恢复该过程。

  • 使用 fetch 方法来上传文件相当容易。 连接断开后如何恢复上传?这里没有对此的内建选项,但是我们有实现它的一些方式。 对于大文件(如果我们可能需要恢复),可恢复的上传应该带有上传进度提示。由于 fetch 不允许跟踪上传进度,我们将会使用 XMLHttpRequest。 不太实用的进度事件 要恢复上传,我们需要知道在连接断开前已经上传了多少。 我们有 xhr.upload.onprogress

  • 我正在测试Android的驱动器API,以便上传一个文件,该文件可以显示上传的进度,并能够在失败时恢复上传(文件大小>30 MB) 与以下问题:上传下载的大文件到谷歌驱动器给错误,上传进度监听器没有激发(谷歌驱动器API)我能够得到上传进度,他们提到那些是可恢复的上传。但是,我没有看到任何寻找上传错误和恢复逻辑的代码,因此,如果我杀死应用程序并“恢复”上传,它只是从头开始。

  • 大部分错误并没有严重到需要程序完全停止执行。有时,一个函数会因为一个容易理解并做出反应的原因失败。例如,如果尝试打开一个文件不过由于文件并不存在而操作失败,这时我们可能想要创建这个文件而不是终止进程。 回忆一下第二章 “使用 Result 类型来处理潜在的错误” 部分中的那个 Result 枚举,它定义有如下两个成员,Ok 和 Err: T 和 E 是泛型类型参数;第十章会详细介绍泛型。现在你需要

  • 突然有一天,糟糕的事情发生了,而你对此束手无策。对于这种情况,Rust 有 panic!宏。当执行这个宏时,程序会打印出一个错误信息,展开并清理栈数据,然后接着退出。出现这种情况的场景通常是检测到一些类型的 bug 而且程序员并不清楚该如何处理它。 当出现 panic! 时,程序默认会开始 展开(unwinding),这意味着 Rust 会回溯栈并清理它遇到的每一个函数的数据,不过这个回溯并清理的

  • 由于同样的原因,com.google.api.client.http.httprequest.execute()总是失败(由于某种原因上传失败(套接字超时..)->重试->获取成功上传的数据大小->500错误) [日志]