Voici mon code pour tester l'exportation de fichiers à partir de google drive côté serveur.Impossible d'exporter une diapositive google au format pdf côté serveur
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)
Du côté client Web, une fois qu'un utilisateur sélectionne un fichier à partir du sélecteur de fichiers, l'avant javascript appellera le /gdrive/selectcallback
dans le code python ci-dessus avec le jeton et id fichier.
À titre d'exemple, le jeton ressemble à quelque chose comme ceci: ya29.Glu5BG-LQJFqZ-e4uImMSxz-14iS41jVLfXk6rVKvAPjylCwhUh98ZJk1iIC5Eb49pTfflGnU6qE7uzK44AYr0Wn79QMUkF368WFaYrhidrvpVjcsJSZ9P1M8VU6
et id fichier ressemble à ceci 1ON9kGyb02TFCygy8jeIYyo2BKj5SzKgAP0xi5Rm08D4
Voici le code frontal concerné (en 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
Basé sur le des informations de débogage, mon code python émet ces deux appels https:
2017-09-01 11:32:38,810 pid 260 tid 140546358265600 INFO
discovery URL being requested: GET https://www.googleapis.com/discovery/v1/apis/drive/v3/rest2017-09-01 11:32:39,009 pid 260 tid 140546358265600 INFO discovery URL being requested: GET https://www.googleapis.com/drive/v3/files/1ON9kGyb02TFCygy8jeIYyo2BKj5SzKgAP0xi4Rm08D4/export?mimeType=application%2Fpdf
Si j'utilise directement la deuxième url dans un large owser, j'obtiens l'erreur suivante:
{
"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."
}
}
(Je ne pense pas que le message d'erreur ci-dessus reflète réellement la cause profonde. Il est plus probable en raison du fait que l'appel n'est pas authentifié dans mon navigateur.)
Je pense que je dois utiliser la bibliothèque google-auth
(https://google-auth.readthedocs.io/en/latest/user-guide.html#making-authenticated-requests), mais je ne suis pas sûr de savoir comment se marier google-auth
au code python I avoir ci-dessus. Je suppose que je peux obtenir un titre via
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(
'/path/to/key.json')
Mais que dois-je faire avec le credentials
après cela? Est-ce que je l'utilise pour remplacer credentials = AccessTokenCredentials(code,'my-user-agent/1.0')
entièrement?
P.S.
Selon la suggestion de @ Tanaike, j'ai essayé d'utiliser directement l'URL de l'API. C'est le résultat que j'ai obtenu:
{
"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."
}
}
Il semble s'agir d'un problème d'API v3. Si je passe en v2 et utilise un lien downloadUrl, je peux télécharger le fichier en format pdf.
ce message d'erreur que vous obtenez de l'API d'exportation? L'exportation via l'explorateur d'API semble fonctionner correctement –
Il arrive à la diapositive particulière comme mentionné dans la question (un lien est également fourni). "Download 0%" a été imprimé plusieurs fois jusqu'à la fin de la procédure. Un 500 est intercepté. –
Vous pouvez vérifier que cette erreur est signalée par [problème (https://issuetracker.google.com/issues/64294118) Drive API renvoie l'erreur 500 Il n'était pas clair si cela fonctionne maintenant pour v3 puisque le rapport a seulement confirmé qu'il fonctionne dans v2. Vous voudrez peut-être suivre le problème, puis en commenter/en créer un nouveau.Espérons que cette aide –