Вот мой код для тестирования экспорта файлов с диска Google на стороне сервера.
import logging
from flask import Flask, render_template, request
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from oauth2client.client import AccessTokenCredentials
import httplib2
import io
app = Flask(__name__)
@app.route('/gdrive/selectcallback')
def userselectioncallback():
print "In user selection callback... "
code = request.args.get('user_token')
fileId = request.args.get('fileId')
credentials = AccessTokenCredentials(code,
'my-user-agent/1.0')
http = httplib2.Http()
http_auth = credentials.authorize(http)
drive_service = build('drive', 'v3', http=http_auth)
drive_request = drive_service.files().export(
fileId=fileId,
mimeType='application/pdf')
fh = io.FileIO('test.pdf', 'wb')
downloader = MediaIoBaseDownload(fh, drive_request)
done = False
while done is False:
status, done = downloader.next_chunk()
print "Download %d%%." % int(status.progress() * 100)
return code
if __name__ == '__main__':
# This is used when running locally. Gunicorn is used to run the
# application on Google App Engine. See entrypoint in app.yaml.
app.run(host='127.0.0.1', port=8090, debug=True)
На стороне веб-клиента, когда пользователь выбирает файл в средстве выбора файлов, внешний интерфейс javascript вызывает /gdrive/selectcallback
в приведенном выше коде Python с токеном и идентификатором файла.
Например, токен выглядит примерно так: ya29.Glu5BG-LQJFqZ-e4uImMSxz-14iS41jVLfXk6rVKvAPjylCwhUh98ZJk1iIC5Eb49pTfflGnU6qE7uzK44AYr0Wn79QMUkF368WFaYrhidrvpVjcsJSZ9P1M8VU6
а идентификатор файла выглядит примерно так 1ON9kGyb02TFCygy8jeIYyo2BKj5SzKgAP0xi5Rm08D4
Вот соответствующий интерфейсный код (в coffeescript):
pickerCallback = () ->
view = new google.picker.View(google.picker.ViewId.PRESENTATIONS)
picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.setAppId('zeetings')
.setOAuthToken(oauthToken)
.addView(view)
.setDeveloperKey(env['googleapi-client'].apiKey)
.setCallback(selectCallback) # The callback calls the python backend
.build()
picker.setVisible true
selectCallback = (data) ->
if data.action is google.picker.Action.PICKED
fileId = data.docs[0].id
fileSelectedCallback(fileId, oauthToken) if fileSelectedCallback
Основываясь на информации об отладке, мой код Python выдает эти два вызова https:
01.09.2017, 11:32:38,810 pid 260 tid 140546358265600 INFO
запрашиваемый URL-адрес обнаружения: GET https://www.googleapis.com/discovery/v1/apis/drive/v3/rest01.09.2017 11:32:39,009 pid 260 tid 140546358265600 Запрашиваемый URL-адрес обнаружения ИНФОРМАЦИИ: GET https://www.googleapis.com/drive/v3/files/1ON9kGyb02TFCygy8jeIYyo2BKj5SzKgAP0xi4Rm08D4/export?2Fpdf
Если я использую второй URL-адрес непосредственно в браузере, я получаю следующую ошибку:
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
(Я не думаю, что приведенное выше сообщение об ошибке на самом деле отражает основную причину. Скорее всего, это связано с тем, что вызов не аутентифицирован в моем браузере.)
Я подозреваю, что мне нужно использовать библиотеку google-auth
(https://google-auth.readthedocs.io/en/latest/user-guide.html#making-authenticated-requests), но я не знаю, как соединить google-auth
с кодом Python, который у меня есть выше. Я полагаю, что могу получить учетные данные через
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(
'/path/to/key.json')
Но что мне делать с credentials
после этого? Могу ли я использовать его, чтобы полностью заменить credentials = AccessTokenCredentials(code,'my-user-agent/1.0')
?
P.S.
Согласно предложению @Tanaike, я попытался напрямую использовать URL-адрес API. Это результат, который я получил:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "fileNotDownloadable",
"message": "Only files with binary content can be downloaded. Use Export with Google Docs files.",
"locationType": "parameter",
"location": "alt"
}
],
"code": 403,
"message": "Only files with binary content can be downloaded. Use Export with Google Docs files."
}
}
Кажется, проблема с v3 API. Если я переключусь на v2 и воспользуюсь ссылкой downloadUrl, я смогу скачать файл в формате pdf.
code = request.args.get('user_token')
? Кажется, это может быть токен обновления. если это токен обновления, могу ли я спросить вас о области действия, включенной в токен обновления? И вы уже включили Drive API в консоли API? - person Tanaike   schedule 04.09.2017curl -L --data "access_token=### access token ###" https://www.googleapis.com/oauth2/v2/tokeninfo
- person Tanaike   schedule 04.09.2017gapi.auth
, а неpicker
:{ "issued_to": "534888811371-fegdtjm9ak4a6nhq2f4ukrjfkgdnv0q6.apps.googleusercontent.com", "audience": "534888811371-fegdtjm9ak4a6nhq2f4ukrjfkgdnv0q6.apps.googleusercontent.com", "scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file", "expires_in": 3309, "access_type": "online" }
- person Anthony Kong   schedule 04.09.2017picker
с использованием токена обновления, который извлекает токен доступа? - person Tanaike   schedule 04.09.2017alt=media
. developers.google.com/drive/v3/reference/files/get - person Tanaike   schedule 04.09.2017export
(developers.google.com/ диск/v3/ссылка/файлы/экспорт). Вот похожее видео на YouTube от команды Google Drive: youtu.be/-7YH6rdR-tk?t =10м33с - person Anthony Kong   schedule 04.09.2017