谷歌硬盘Python API可恢复上传错误401 2小时后

2024-09-27 19:28:22 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,我很抱歉如果这是一个太愚蠢的问题。。。这是我第一次尝试使用这个脚本中涉及的任何技术(Python、driveapi、oauth2.0等)。我发誓在发布问题之前我已经搜索并尝试了大约一个星期。呵呵

我正在尝试使用googleapi python客户端来上传一个大文件(3.5GiB),这个文件只在终端linuxdebian上。我已经成功地上传了一些小文件,但是当我试图上传大文件时,上传在它开始1~2小时后停止,并出现了http401错误(未经授权)。我一直在研究如何获得一个新的访问令牌,但收效甚微。在

这是我目前(更新的)代码:

#!/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后会自动刷新访问令牌。虽然它确实在更改访问令牌,但仍然没有按预期继续上载。。。见以下输出:

^{pr2}$

我使用DebianLenny安装了Python2.5.2,并在大约一周前通过pip安装安装安装了ssl和GoogleAPI Python客户端。在

提前谢谢你的帮助。在

编辑:显然,问题不在于api。我尝试了上面相同的代码,但是使用了两个小文件,它们之间间隔1h(系统睡眠()). 结果是:

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

对于第二次上载,已成功使用新的访问令牌。那么,也许可恢复会话在一段时间后将过期,或者只对特定的访问令牌有效?在


Tags: 文件fromimportclienthttpstatusbodydrive
2条回答

我提交了一个issue on the google-api-python-client project,据来自谷歌的Joe Gregorio说,问题出在后端:

“这是后端的问题,而不是API或您的代码。正如您所推断的,如果上载时间过长,access_token将过期,此时无法继续进行可恢复上载。目前正在进行修复此问题的工作,一旦服务器端的问题得到修复,我将更新此错误。“

我假设问题是在1-2小时后,您对远程数据库的访问令牌将过期;切断与远程服务器的连接。我想你可以看看你的主机API手册。。。他们应该有一些关于“刷新令牌”的东西(他们给你另一个访问令牌,注意一些主机只允许你在每个会话中使用一个刷新令牌),如果允许无限量,你可以使用定时器和AJAX的组合来不断请求更多的访问令牌。在

如果没有,那么您将需要对另一个授权令牌发出AJAX请求,并每隔一小时将其交换为另一个访问令牌。这听起来是一个非常严格的过程,但我认为这是唯一的办法,如果你的代币不断到期。在

另外还有一个问题,你有没有试过其他上传的方法?如果你说上面的脚本运行了1-2个小时,它只上传了文件的1.44%,可能需要100多个小时才能完全上传(对于3个gig来说太长了)。在

相关问题 更多 >

    热门问题