Access Google spreadsheet from Google Appengine with service account : working once per hour

柔情痞子 提交于 2020-01-01 19:13:11

问题


I have implemented the python code here below based on the documentation in order to access a spreadsheet accessible through a public link. It works once every hour. If I execute a few seconds after a success, I receive an error :

Error opening spreadsheet no element found: line 1, column 0

Assumption: The access token has an expiry date of 1 hour. So the appengine would proceed to a token refresh after an hour, resetting the whole.

Question: This code requests a new token for each request. So what should I do ? Save the token ? When I try the token_to_blob in order to save the token, I get an error : Scope undefined

Thanks in advance for your help !

    try :
        credentials = AppAssertionCredentials(scope=('https://www.googleapis.com/auth/drive','https://spreadsheets.google.com/feeds','https://docs.google.com/feeds'))
        logging.info("credentials")
        http_auth = credentials.authorize(httplib2.Http())
        authclient = build('oauth2','v2',http=http_auth)
        auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
    except Exception as details:
        logging.error("Error Google credentials %s"%details)
        return "Error"

    try :
        gd_client = gdata.spreadsheets.client.SpreadsheetsClient()
        gd_client = auth2token.authorize(gd_client)
        feed = gd_client.GetListFeed(<spreadsheetKey>,1)
    except Exception as details:
        logging.error("Error opening spreadsheet %s"%details)
        return "Error"

回答1:


I finally declared the credentials & the token as global. In this case, it was working for several subsequent requests but after 1 hour, the token was invalid.

I tested with the method access_token_expired but this method always returned false.

So, I finally execute the refresh systematically and it works. Not elegant but functional. Another option would be to store the time of next refresh and only refresh after 1 hour.

Your comments are welcome for elegant alternatives.

I did not try gspread since the rest of the code was already functional for gdata.spreadsheets but perhaps I should.

from oauth2client.contrib.appengine import AppAssertionCredentials
from oauth2client.client import Credentials
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build
import httplib2

global credentials
global auth2token
try :
    credentials = AppAssertionCredentials(scope=('https://www.googleapis.com/auth/drive','https://spreadsheets.google.com/feeds','https://docs.google.com/feeds'))
    http_auth = credentials.authorize(httplib2.Http())
    authclient = build('oauth2','v2',http=http_auth)
    auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
except Exception as details:
    logging.error("Error Google credentials %s"%details)

class importFromSpreadsheet(webapp2.RequestHandler):
    def __importFromSpreadsheet(self,u):
        try :
            credentials._refresh(httplib2.Http())
        except Exception as details:
            logging.error("Error refreshing Google credentials %s"%details)
...
        try :
            gd_client = gdata.spreadsheets.client.SpreadsheetsClient()
            gd_client = auth2token.authorize(gd_client)
            feed = gd_client.GetListFeed(u,1)
        except Exception as details:
            logging.error("Error opening 1st spreadsheet %s"%details)
            return "Error"


来源:https://stackoverflow.com/questions/36081860/access-google-spreadsheet-from-google-appengine-with-service-account-working-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!