How to cache authorization for Google Sheets using gspread?

Question:

I am trying to create a simple function that posts some data to a Google Sheets spreadsheet. I am hosting this function in AWS Lambda. Anyway, the code looks kinda like this:

import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = [
    'https://spreadsheets.google.com/feeds',
    'https://www.googleapis.com/auth/drive'
]
credentials = ServiceAccountCredentials.from_json_keyfile_name(
    'my_creds.json', scope
)
gc = gspread.authorize(credentials)

This works perfectly, but unfortunately, the process is pretty slow. The bulk of the time it seems is taken to authorize. So my question is this: is there some way to authorize and save the authorization object and re-use it for the next few requests? Once the validity runs out, the function can authorize it again. Any help is greatly appreciated!

Asked By: darkhorse

||

Answers:

  • You don’t want to run the authorize process every run.
  • You want to save the authorization data to a file and want to use gspread by loading it.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

In this answer, the token information including the access token are saved as a file. Because the expiration time of access token is 3600 seconds. This is used.

Flow:

The flow of this answer is as follows.

  1. Check the token file including the authorization data.
    • If the file is NOT existing, the access token is retrieved by the authorization process and save the token information to the token file.
    • If the file is existing and the limitation time is more than the current time, the access token retrieved from the token file is used.
    • If the file is existing and the limitation time is less than the current time, the access token is retrieved by the authorization process and save the token information to the token file.
  2. Use gspread using the access token.

By this flow, the authorization process is run every about 1 hour instead of every run.

Sample script:

Before you run the script, please modify the variables of token_file and credential_file.

import datetime
import gspread
import json
import os
from oauth2client.service_account import ServiceAccountCredentials
from oauth2client.client import AccessTokenCredentials


token_file = "./access_token.txt"  # token file including the authorization data
credential_file = "###credential file of service account###"
now = int(datetime.datetime.now().timestamp())


def getNewAccessToken():
    scope = ['https://www.googleapis.com/auth/spreadsheets']
    credentials = ServiceAccountCredentials.from_json_keyfile_name(credential_file, scope)
    gc = gspread.authorize(credentials)
    token_response = gc.auth.token_response
    token_response['limitTime'] = token_response['expires_in'] + now - 300
    with open(token_file, mode='w') as f:
        json.dump(token_response, f)
    return token_response['access_token']


def getCredential():
    access_token = ""
    if os.path.exists(token_file):
        with open(token_file) as f:
            token = json.load(f)
        access_token = token['access_token'] if token['limitTime'] > now else getNewAccessToken()
    else:
        access_token = getNewAccessToken()
    return AccessTokenCredentials(access_token, None)


# Use gspread
credentials = getCredential()
gc = gspread.authorize(credentials)
  • In above script, the limitation time of the access token is set as 3600 - 300 seconds. Because if the limitation time is set as 3600 seconds, an error of authorization might occur during the script is running.

Reference:

If I misunderstood your question and this was not the direction you want, I apologize.

Updated on February 16, 2023

In the current stage, it seems that gspread uses google-auth. By this, when this script is run with the current gspread, an error occurs. So, I posted the updated script for this to this thread. If you want to use this method using the current gspread, please check that thread.

Answered By: Tanaike
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.