gspread w/ OAuth2Client Service Account Key

2019-01-29 10:28发布

问题:

I am using gspread and a Service Account Key, Other, json file. to continually update a google spreadsheet with python 2.7. I have this running off a Raspberry Pi running the latest Raspian Jessie. my oauth and gspread should all be the latest versions available for my platform. My script runs for one hour(the max token life span),then stops working with the error message : "Invalid token: Statless token expired error" My code is as follows

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import httplib2
from httplib2 import Http

scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name(filename.json,scope)
gc = gspread.authorize(credentials)
wks = gc.open('spreadsheet name')
p1 = wks.worksheet('Printer One')

def functon()
...
p1.append_row(printing)

Any Help would be greatly appreciated, Thank You.

回答1:

Authorisation expires every 0.5/1 hour (I think it depends on which of the two available methods you use to connect).

I have a google sheet connected 24/7 that updates every 2 seconds. Almost always the reason for a bad read/write is an authorisation error but also Google API can throw a variety of errors at you too that normally resolve after a few seconds. Here's one of my functions to update a cell, but using your details for auth_for_worksheet. Every operation (update single cell, update a range, read a column of values) has some similar construct as a function, which always returns an authorised worksheet. It's probably not the most elegant solution but the sheet has been connected for 3 months fine with no downtime.

def auth_for_worksheet():
    scope = ['https://spreadsheets.google.com/feeds']
    credentials = ServiceAccountCredentials.from_json_keyfile_name(filename.json,scope)
    gc = gspread.authorize(credentials)
    wks = gc.open('spreadsheet name')
    p1 = wks.worksheet('Printer One')
    return p1

def update_single_cell(worksheet, counter, message):
    """ No data to return, update a single cell in column B to reflect this """

    single_cell_updated = False
    while not single_cell_updated:
        try:
            cell_location = "B" + str(counter)
            worksheet.update_acell(cell_location, message)
            single_cell_updated = True
        except gspread.exceptions.HTTPError:
            logger.critical("Could not update single cell")
            time.sleep(10)
            worksheet = auth_for_worksheet()
    logger.info("Updated single cell")
    return worksheet

if __name__ == '__main__':

    # your code here, but now to update a single cell
    wksheet = update_single_cell(wksheet, x, "NOT FOUND")