Search code examples
pythonubuntugoogle-drive-apigoogle-oauthpydrive

pydrive: trying to upload files to Google Drive from a remote server


I am trying to upload files to google drive automatically with a python script working remotely from a (Ubuntu) server.

In my code I have the following simple lines from Pydrive:

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)

file = drive.CreateFile({"parents": [{"kind": "<directory_name>","id": "<directory_id>"}]})
file.SetContentFile('<file_name>')
file.Upload()

I have a setting.yaml file in my python directory so that the script can authenticate itself automatically after the first manual authentication, and a client_secrets.json. I basically followed all the steps in https://pythonhosted.org/PyDrive/oauth.html.

However, when I activate my script on the remote Ubuntu server, I am connected to a google page on the terminal environment asking me for my email address and password. When I enter these, Google asks for a second authentication: either look at an image with a code (and nothing shows up on terminal), or "listen and type the number that you hear". When I type on that command, the terminal replies "is not found" and I cannot hear anything (see picture below).

enter image description here

I am stuck and I do not know how to circumnavigate this problem. I unfortunately need to authenticate at least once, then the script will authenticate itself automatically. I really do not see how to skip that step.

Any idea / comment / insight would be greatly appreciated

Thank you so much Berti


Solution

  • As mentioned in the docs:

    You can also use CommandLineAuth() which manually takes code from user at command line.

    The LocalWebserverAuth() will spawn a local webserver listening (by default) on localhost:8080, and attempt to open an authentication URL on the user's web browser. The opened page will, after authentication, communicate the authentication codes to the local server running on localhost.

    The problem here is that running this code on your remote server cannot open the link in the browser on your local machine, and thus, you cannot login.

    Using CommandLineAuth() will instead print out a URL on the remote server's terminal, which you can open in your local browser. You then authenticate in your browser, which gives you the authentication codes, which you need to copy from your local browser and paste into the prompt in the terminal.

    from pydrive.auth import GoogleAuth
    from pydrive.drive import GoogleDrive
    
    gauth = GoogleAuth()
    gauth.CommandLineAuth()  # <--
    drive = GoogleDrive(gauth)
    
    file = drive.CreateFile({"parents": [{"kind": "<directory_name>","id": "<directory_id>"}]})
    file.SetContentFile('<file_name>')
    file.Upload()
    

    If you want to automatically distinguish between local and remote machines to choose the authentication method, I'd recommend to check out these questions: