Ошибка повторной загрузки Google Drive Python API 401 через 2 часа
Прежде всего, извините, если это слишком глупый вопрос... это первый раз, когда я пытаюсь использовать любую из технологий, задействованных в этом сценарии (Python, API-интерфейс диска, oauth 2.0 и т. Д.). Клянусь, я искал и пробовал это примерно неделю, прежде чем опубликовать вопрос. хехехе
Я пытаюсь использовать google-api-python-client для загрузки большого файла (3,5 ГБ), который находится на терминале только в Linux Debian. У меня был некоторый успех при загрузке небольших файлов, но когда я пытаюсь загрузить большой файл, загрузка останавливается примерно через 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.
Я использую debian lenny с установленным Python 2.5.2 и установил ssl и google-api-python-client с помощью установки pip около недели назад.
Заранее благодарю за любую помощь.
РЕДАКТИРОВАТЬ: Видимо, проблема не с API. Я попробовал тот же код выше, но с двумя небольшими файлами, с 1 ч между ними (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 ответа
Я подал проблему в проект google-api-python-client, и, по словам Джо Грегорио из Google, проблема в бэкэнде:
"Это проблема с серверной частью, а не с API или с вашим кодом. Как вы поняли, если загрузка идет слишком долго, срок действия access_token истекает, и в этот момент возобновляемая загрузка не может быть продолжена. исправить эту проблему прямо сейчас, я буду обновлять эту ошибку, как только проблема будет устранена на стороне сервера."
Я предполагаю, что проблема в том, что по истечении 1-2 часов ваш токен доступа к удаленной базе данных истекает; разрыв связи с удаленным сервером. Я думаю, что вы могли бы сделать, это взглянуть на руководство по API вашего хоста... У них должно быть что-то там о "токенах обновления" (они дают вам еще один токен доступа, обратите внимание, что некоторые хосты позволяют использовать только один токен обновления для сеанса), если им разрешено неограниченное количество, вы можете использовать комбинацию таймера и AJAX, чтобы продолжать запрашивать больше токенов доступа.
Если нет, то вы должны сделать AJAX-запрос на другой токен авторизации и обменивать его на другой токен доступа каждый час. Это звучит как очень строгий процесс, но я думаю, что это единственный способ, если срок действия вашего токена истекает.
Также просто на другой ноте вы пробовали другие способы загрузки? Если вы сказали, что вышеприведенный скрипт выполнялся в течение 1-2 часов, и он загрузил только 1,44% файла, для полной загрузки которого может потребоваться более 100 часов (слишком долго для 3 гигабайт).