5

まず第一に、これがばかげた質問でしたら申し訳ありません... このスクリプトに関連するテクノロジ (Python、ドライブ API、oauth 2.0 など) を使用しようとするのはこれが初めてです。質問を投稿する前に、これを約1週間検索して試してみたことを誓います。へへへ

Linux Debian のみの端末にある大きなファイル (3.5GiB) をアップロードするために google-api-python-client を使用しようとしています。小さいファイルのアップロードには成功していますが、大きいファイルをアップロードしようとすると、開始から約 1 ~ 2 時間後に HTTP 401 エラー (未承認) でアップロードが停止します。新しいアクセストークンを取得する方法を探していましたが、ほとんど成功していません.

これはこれまでの私の(更新された)コードです:

#!/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 を使用しており、約 1 週間前に pip install を介して ssl と google-api-python-client をインストールしました。

助けてくれてありがとう。

編集:どうやら、問題は api ではありません。上記と同じコードを試しましたが、2 つの小さなファイルがあり、その間に 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!

2 回目のアップロードでは、新しいアクセス トークンが正常に使用されました。では、再開可能なセッションはしばらくして期限切れになるのでしょうか、それともその特定のアクセス トークンに対してのみ有効なのでしょうか?

4

2 に答える 2

4

私はgoogle-api-python-client プロジェクトに問題を提出しました。Google のJoe Gregorio によると、問題はバックエンドにあります。

「これはバックエンドの問題であり、API やコードの問題ではありません。あなたが推測したように、アップロードが長すぎると access_token の有効期限が切れ、その時点で再開可能なアップロードを続行できません。進行中の作業があります。今すぐこの問題を修正してください。問題がサーバー側で修正されたら、このバグを更新します。」

于 2013-01-14T15:02:02.260 に答える
0

問題は、1 ~ 2 時間の制限の後、リモート データベースへのアクセス トークンの有効期限が切れることだと思います。リモートサーバーとの接続を切断します。あなたができることは、あなたのホスト API マニュアルを見ることだと思います...彼らはそこに「リフレッシュトークン」について何かを持っているはずです(彼らはあなたに別のアクセストークンを取得します、いくつかのホストはセッションごとに1つのリフレッシュトークンしか使用できないことに注意してください)、それらが無制限に許可されている場合は、タイマーと AJAX の組み合わせを使用して、より多くのアクセス トークンを要求し続けることができます。

そうでない場合は、別の認証トークンの AJAX 要求を作成し、それを別のアクセス トークンと 1 時間ごとに交換する必要があります。これは非常に厳格なプロセスのように聞こえますが、トークンの有効期限が切れ続ける場合は、それが唯一の方法だと思います。

また、別の注意点として、他のアップロード方法を試しましたか? 上記のスクリプトが 1 ~ 2 時間実行され、完全にアップロードするのに 100 時間以上かかる可能性があるファイルの 1.44% しかアップロードされなかったとします (わずか 3 ギグには長すぎます)。

于 2013-01-11T21:08:31.393 に答える