J'essaie d'automatiser le processus GoogleAuth
lorsque j'utilise la bibliothèque pydrive
( https://pypi.python.org/pypi/PyDrive ).
J'ai configuré les API pydrive et google de sorte que mon secret_client.json
fonctionne, mais une authentification Web est nécessaire pour accéder à gdrive chaque fois que j'exécute mon script:
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
eng.txt
est juste un fichier texte. De plus, lorsque j'essaie d'utiliser le script ci-dessus alors que je suis connecté à un autre compte. Il ne télécharge pas le eng.txt
dans mon lecteur qui a généré le secret_client.json
mais le compte qui a été connecté lorsque j'autorise l'authentification
Dans le post précédent, j'ai essayé ce qui suit pour automatiser le processus de vérification, mais cela donne des messages d'erreur:
import base64, httplib2
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
#gauth = GoogleAuth()
#gauth.LocalWebserverAuth()
# from google API console - convert private key to base64 or load from file
id = "464269119984-j3oh4aj7pd80mjae2sghnua3thaigugu.apps.googleusercontent.com"
key = base64.b64decode('COaV9QUlO1OdqtjMiUS6xEI8')
credentials = SignedJwtAssertionCredentials(id, key, scope='https://www.googleapis.com/auth/drive')
credentials.authorize(httplib2.Http())
gauth = GoogleAuth()
gauth.credentials = credentials
drive = GoogleDrive(gauth)
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
Erreur:
Traceback (most recent call last):
File "/home/alvas/git/SeedLing/cloudwiki.py", line 29, in <module>
textfile.Upload()
File "/usr/local/lib/python2.7/dist-packages/pydrive/files.py", line 216, in Upload
self._FilesInsert(param=param)
File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 53, in _decorated
self.auth.Authorize()
File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 422, in Authorize
self.service = build('drive', 'v2', http=self.http)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/apiclient/discovery.py", line 192, in build
resp, content = http.request(requested_url)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 475, in new_request
self._refresh(request_orig)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 653, in _refresh
self._do_refresh_request(http_request)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 677, in _do_refresh_request
body = self._generate_refresh_request_body()
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 861, in _generate_refresh_request_body
assertion = self._generate_assertion()
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 977, in _generate_assertion
private_key, self.private_key_password), payload)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/crypt.py", line 131, in from_string
pkey = crypto.load_pkcs12(key, password).get_privatekey()
OpenSSL.crypto.Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]
Mon authentification sur gdrive api ressemble à ceci:
Comment utiliser pydrive pour ne pas avoir à m'authentifier chaque fois que je l'utilise?
Comment autoriser l'authentification automatique de sorte que le script python utilisant le script pydrive ne charge que sur le compte qui a généré le secret_client.json
et non le compte actuellement connecté sur le navigateur Internet?
Tout d'abord, vous comprenez mal comment cela fonctionne:
lorsque j'essaie d'utiliser le script ci-dessus pendant que je suis connecté à un autre Compte. Il ne charge pas le fichier eng.txt dans mon disque qui a généré le secret_client.json mais le compte qui a été connecté quand je autoriser l'authentification
C'est exactement comme ça que ça doit fonctionner. En tant que développeur, vous distribuez client_secret.json
avec votre application. Ce fichier est utilisé par PyDrive pour authentifier l'application avec Google. Google souhaite connaître le nombre de requêtes API émises par chaque application pour diverses raisons (métriques, facturation du compte, accès révoqué, etc.). Il est donc nécessaire que l'application s'authentifie elle-même.
Désormais, lorsque votre application exécute LocalWebserverAuth
, elle authentifie le client avec Google. Bien entendu, le client est la personne qui utilise réellement votre application. Dans ce cas, le développeur et le client sont la même personne (vous), mais imaginez que vous souhaitiez distribuer votre application à un million de personnes différentes. Ils doivent être en mesure de s'authentifier et de télécharger des fichiers sur leur propre compte Drive, plutôt que de les avoir tous dans le vôtre (le développeur), qui a fourni client_secret.json
.
Cela dit, il ne s'agit que d'un changement très mineur, de sorte que votre application n'a pas à demander au client de s'authentifier chaque fois que vous l'exécutez. Vous devez juste utiliser LoadCredentialsFile
et SaveCredentialsFile
.
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gauth = GoogleAuth()
# Try to load saved client credentials
gauth.LoadCredentialsFile("mycreds.txt")
if gauth.credentials is None:
# Authenticate if they're not there
gauth.LocalWebserverAuth()
Elif gauth.access_token_expired:
# Refresh them if expired
gauth.Refresh()
else:
# Initialize the saved creds
gauth.Authorize()
# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
Une autre méthode consiste à utiliser un flux d'authentification personnalisé en écrivant un fichier setting.yaml dans le répertoire de travail. Et cette méthode fonctionne mieux, car LocalWebserverAuth()
générera un jeton qui expire dans une heure et ne contient pas de jeton d'actualisation.
Un exemple de fichier settings.yaml ressemble à ceci
client_config_backend: file
client_config:
client_id: <your_client_id>
client_secret: <your_secret>
save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json
get_refresh_token: True
oauth_scope:
- https://www.googleapis.com/auth/drive
- https://www.googleapis.com/auth/drive.install
Avec ce fichier, vous devez toujours utiliser un navigateur pour effectuer l'authentification pour la première fois, puis un fichier credentials.json sera généré dans le répertoire de travail avec un jeton d'actualisation.
Cette méthode fonctionne mieux si vous essayez d'automatiser votre script sur le serveur.
Si les informations d'identification ne sont pas en place, ce code génère une zone de saisie avec deux options:
Authentification du navigateur (que vous devez faire une seule fois)
Téléchargement du fichier d’identifiants (ce fichier sera généré la première fois que vous choisissez pour l’authentification du navigateur)
Maintenant, il est facile de partager le bloc-notes, qui s'exécutera sans demander d'autorisation, puisqu'il utilisera les informations d'identification enregistrées dans mycreds.txt à partir de l'environnement local. Cependant, si le moteur d'exécution se bloque ou est réinitialisé, ce fichier sera perdu et il devra être réinséré via la zone de saisie ci-dessus. Bien sûr, vous pouvez le faire à nouveau via l'authentification du navigateur, mais si vous redistribuez mycreds.txt aux utilisateurs du bloc-notes, ils peuvent utiliser la fonction Télécharger pour insérer les informations d'identification dans l'environnement local.
Les dernières lignes fournissent simplement un exemple de la manière dont un fichier csv du lecteur authentifié peut être téléchargé et utilisé dans le bloc-notes.
#Install the required packages and fix access to my Google drive account
!pip install pydrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
#Checks for file with Google authentication key, if the file is not in place, it asks to authenticate via the browser
gauth = GoogleAuth()
if os.path.isfile("mycreds.txt") is False:
choice = input ("Do you want to: U) Upload authentication file (mycreds.txt). B) Browser authentication (only possible for owner of the connected Google drive folder). [U/B]? : ")
if choice == "U":
print ("Upload the mycreds.txt file")
from google.colab import files
files.upload()
Elif choice == "B":
auth.authenticate_user()
gauth.credentials = GoogleCredentials.get_application_default()
gauth.SaveCredentialsFile("mycreds.txt")
gauth.LoadCredentialsFile("mycreds.txt")
if gauth.access_token_expired:
gauth.Refresh()
else: gauth.Authorize()
#Now you can easily use the files from your drive by using their ID
drive = GoogleDrive(gauth)
download = drive.CreateFile({'id': '1KRqYpR9cteX-ZIwhdfghju6_wALl4'})
download.GetContentFile('my_data.csv')
data_frame = pd.read_csv('my_data.csv')
Ceci est juste pour compléter @ wang892 post ci-dessus (je n'ai pas assez de réputation pour commenter).
Cette réponse m'a aidé à automatiser mon script (ne pas avoir à me réauthentifier à chaque fois que je l'exécute).
Mais comme j'ai utilisé l'exemple de fichier settings.yaml disponible dans la documentation PyDrive , j'ai rencontré des problèmes (en raison de ma totale ignorance sur le fonctionnement de oauth).
Cet exemple de fichier contient les lignes suivantes, qui, à mon avis, limitaient l'accès du script PyDrive aux seuls fichiers et dossiers créés par lui-même (voir numéro de PyDrive n ° 122 pour plus de détails):
Accès limité:
oauth_scope:
- https://www.googleapis.com/auth/drive.file
- https://www.googleapis.com/auth/drive.install
Lorsque j'ai modifié ces lignes, le problème a été résolu (je devais supprimer mes informations d'identification stockées et exécuter le script pour le réautoriser, encore une fois).
Avec ces nouvelles lignes, mon script a désormais accès à tous les fichiers de mon Google Drive:
Accès total:
oauth_scope:
- https://www.googleapis.com/auth/drive
Un peu plus à ce sujet dans Le numéro 108 de PyDrive , qui m'a beaucoup éclairé.