0

In order not to need to create a new service each time I need it (sometimes I use it 8 times per code loop), I create a global object:

import gspread

client_gspread = None
def send_sheet(id_sheet, page_sheet, sheet_data):
    global client_gspread
    if not client_gspread:
        client_gspread = gspread.service_account(filename='client_secret.json')

    sheet = client_gspread.open_by_key(id_sheet).worksheet(page_sheet)
    sheet.clear()
    sheet.update([sheet_data.columns.values.tolist()] + sheet_data.values.tolist())
    print(client_gspread.auth.expiry)

When printing client_gspread.auth.expiry, it will always deliver the original expiration value, but I already let my code looping using the same service for more than 24 hours, so the expiration value that is delivered (1 hour to expire), it is not fixed, it updates if the service is used for any action on the worksheets.

How do I get to look at the updated expiration value so I can put an update possibility in case the expiration time happens?

Tanaike
  • 181,128
  • 11
  • 97
  • 165
Digital Farmer
  • 1,705
  • 5
  • 17
  • 67

1 Answers1

1

I believe your goal is as follows.

  • You want to use the retrieved access token in 1 hour until the expiration time rather than the access token being retrieved every run of the script.
  • You want to use the access token retrieved by the service account.

Modification points:

When the gspread has used oauth2client, this method could be used. But, in the current stage, it seems that the gspread uses google-auth. In this case, the access token is automatically retrieved in the internal library side. By this, this method cannot be used.

It is required to update the script of that method for google-auth.

In this answer, I would like to propose a sample script using google-auth for achieving your goal. The sample script is as follows.

Sample script:

Please set the filename with the path of the credential file of your service account to service_account_credential_file.

import json
from datetime import datetime, timezone
import os
import sys
import google.auth.transport.requests
from google.oauth2 import service_account
from google.oauth2.credentials import Credentials
import gspread

service_account_credential_file = "###"  # Please set the credential file of your service account.
scopes = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/spreadsheets"]
access_token_file = "./sample_token.txt"  # Access token is stored this file.


class GetCredential:
    def __writeObj(self):
        creds = service_account.Credentials.from_service_account_file(service_account_credential_file, scopes=scopes)
        request = google.auth.transport.requests.Request()
        creds.refresh(request)
        access_token = creds.token
        token_obj = {"token": access_token, "expiry": creds.expiry.replace(tzinfo=timezone.utc).timestamp()}
        f = open(access_token_file, "w")
        f.write(json.dumps(token_obj))
        return access_token

    def do(self):
        access_token = None
        if os.path.exists(access_token_file):
            f = open(access_token_file, "r")
            token_obj = json.load(f)
            access_token = token_obj.get("token", None)
            now = datetime.now(timezone.utc).timestamp()
            if int(token_obj.get("expiry", 0)) < int(now) - 5 * 60:
                access_token = self.__writeObj()

        else:
            access_token = self.__writeObj()

        if not access_token:
            print("No access token.")
            sys.exit()
        return Credentials(access_token)


gc = gspread.authorize(GetCredential().do())

# do something

The flow of this script is as follows.

  1. When this script is run for the first time, the access token is retrieved from the server side with the service account, and the retrieved access token is stored in the file of access_token_file. And, you can use the gspread client as gc.

  2. When this script is run, again, when the expiration time is not finished the access token is retrieved from the file of access_token_file. And, you can use the gspread client as gc.

  3. When this script is run, again, when the expiration time has already finished, the access token is retrieved from the server side with the service account. And, you can use the gspread client as gc.

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165