Access Google spreadsheet from Google Appengine with service account : working once per hour
Question: 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"
    


Answer: 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"
    

