How to use google drive API without web browser

3.8k views Asked by At

I am writing a python script that is trying to backup all needed configuration files from my Linux VM to Google Drive Cloud. I would like to do it automatically, without entering the verification code from browser every time script starts. Could you please advise me how to do this?

#!/usr/bin/python

import httplib2
import pprint
import credentials as cred
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
from oauth2client.client import OAuth2WebServerFlow, FlowExchangeError

# Path to the file to upload
FILENAME = 'hello.py'

# Run through the OAuth flow and retrieve credentials from credentials.py


def api_upload(FILENAME):

    flow = OAuth2WebServerFlow(cred.credentials['CLIENT_ID'], cred.credentials['CLIENT_SECRET'],
                               cred.credentials['OAUTH_SCOPE'],
                               redirect_uri=cred.credentials['REDIRECT_URI'])

    authorize_url = flow.step1_get_authorize_url()
    print 'Go to the following link in your browser: ' + authorize_url
    code = raw_input('Enter verification code: ').strip()

    credentials = ''
    try:
        credentials = flow.step2_exchange(code)
    except FlowExchangeError:
        print "Your verification code is incorrect or something else is broken."
        exit(1)

    # Create an httplib2.Http object and authorize it with our credentials
    http = httplib2.Http()
    http = credentials.authorize(http)

    drive_service = build('drive', 'v2', http=http)

    # Insert a file
    try:
        media_body = MediaFileUpload(FILENAME, mimetype='text/plain',     resumable=True)
        body = {
            'title': "" + FILENAME,
            'description': 'A test document',
            'mimeType': 'text/plain'
        }
        upload_file = drive_service.files().insert(body=body, media_body=media_body).execute()
        pprint.pprint(upload_file)
    except IOError:
        print "No such file"
        exit(1)

# Function usage:
api_upload(FILENAME)

Here is my sample function.

Another file stores the credentials for request:

credentials = {"CLIENT_ID": 'blablabla',
               "CLIENT_SECRET": 'blablabla',
               "OAUTH_SCOPE": 'https://www.googleapis.com/auth/drive',
               "REDIRECT_URI": 'urn:ietf:wg:oauth:2.0:oob'}
1

There are 1 answers

0
ELNJ On BEST ANSWER

Basically, you want to separate this script into two separate scripts, one that gets a code and exchanges it for an access token, and one that uses the access token to access your Google Drive. I'd split the above code into two chunks, with the following changes.

In the first part, you can proceed as you do above, but in your initial query to get the code, set access_type to 'offline' and approval_prompt to 'force' (see https://developers.google.com/identity/protocols/OAuth2WebServer). If you do that, then when you exchange the code, the returned token will contain not only an access_token but also a refresh_token that can be used to refresh the access token indefinitely. So then this first script should just save those tokens to a file and exit. If you can make this work, then you only need to run that bit of code (with its manual intervention) once.

Then your second script can just load those saved tokens from the file whenever it needs to run, and access your docs without you having to intervene.