web-dev-qa-db-fra.com

Automatisation du processus de vérification pydrive

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:

enter image description here

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?

40
alvas

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')
72
dano

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.

5
wang892

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')
0
Ger

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é.

0
abu