Automating pydrive verification process Automating pydrive verification process python python

Automating pydrive verification process


First, you're misunderstanding one very important bit of how this works:

when I try to use the above script while I am logged into another account. It doesn't upload the eng.txt into my gdrive that generated the secret_client.json but the account that was logged in when I authorize the authentication

This is exactly how it's supposed to work. You, as the developer, distribute client_secret.json with your application, and that file is used by PyDrive to authenticate the application with Google. Google wants to know how many API requests are being made by each application out there for all sorts of reasons (metrics, charge the account, revoke access, etc.), so it requires the application to authenticate itself.

Now, when your application runs LocalWebserverAuth, it's authenticating the client with Google. The client, of course, is the person actually using your application. In this case, the developer and client are the same person (you), but imagine your want to distribute your application to a million different people. They need to be able to authenticate themselves and upload files to their own Drive account, rather that having them all end up in yours (the developer), who provided client_secret.json.

That said, it's really just a very minor change to make it so your app doesn't have to ask the client to authenticate every time you run the app. You just need to use LoadCredentialsFile and SaveCredentialsFile.

from pydrive.auth import GoogleAuthfrom pydrive.drive import GoogleDrivegauth = GoogleAuth()# Try to load saved client credentialsgauth.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 filegauth.SaveCredentialsFile("mycreds.txt")drive = GoogleDrive(gauth)textfile = drive.CreateFile()textfile.SetContentFile('eng.txt')textfile.Upload()print textfiledrive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')


An alternative way is to use a custom auth flow by writing a setting.yaml file into the working directory. And this method works better as LocalWebserverAuth() will generate a token that expires in just one hour and there is no refresh token.

A sample settings.yaml file looks like this

client_config_backend: fileclient_config:    client_id: <your_client_id>    client_secret: <your_secret>save_credentials: Truesave_credentials_backend: filesave_credentials_file: credentials.jsonget_refresh_token: Trueoauth_scope:    - https://www.googleapis.com/auth/drive    - https://www.googleapis.com/auth/drive.install

With this file, you still have to use a browser to complete authentication for the first time, and after that a credentials.json file will be generated in the working directory with a refresh token.

This method works better if you are trying to automate your script on server


This whole thread helped me a lot, but after I implemented all the solutions presented here one more issue came along: LocalWebserverAuth() won't get the refresh token.

If you open the "mycreds.txt" generated after you implement @dano's code, you'll see that the "refresh token" will be set to "null". After a couple of hours, the token expires and you get the following and end up having to manually authenticate again.

The error:

raise RefreshError('No refresh_token found.') pydrive.auth.RefreshError: No refresh_token found.Please set access_type of OAuth to offline.

The solution for that is to force the approval_promt and set access_type to offline on the flow params of the GoogleAuth.

Here's how I got no more errors:

gauth = GoogleAuth()# Try to load saved client credentialsgauth.LoadCredentialsFile("mycreds.txt")if gauth.credentials is None:    # Authenticate if they're not there    # This is what solved the issues:    gauth.GetFlow()    gauth.flow.params.update({'access_type': 'offline'})    gauth.flow.params.update({'approval_prompt': 'force'})    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 filegauth.SaveCredentialsFile("mycreds.txt")  drive = GoogleDrive(gauth)

Thank you all!