gspread: Intermittent 401 Unauthorized errors

Sometimes works, sometimes doesn’t. Restarting the app helps. Could this be because there is a long lag time between an authorization of a credential with gspread.authorize and then taking actions on the session?

HTTPError: 401: <HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
Traceback (most recent call last):
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/mark/timeobserver/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/mark/timeobserver/server.py", line 42, in toggleWork
    worksheet.append_row([session.timeStarted, datetime.datetime.now(), session.durationWorked, session.durationInterrupted, datetime.datetime.now() - session.timeStarted, session.interruptions])
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/models.py", line 525, in append_row
    self.add_rows(1)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/models.py", line 507, in add_rows
    self.resize(rows=self.row_count + rows)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/models.py", line 488, in resize
    feed = self.client.get_feed(self_uri)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/client.py", line 256, in get_feed
    r = self.session.get(url)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/httpsession.py", line 75, in get
    return self.request('GET', url, **kwargs)
  File "/home/mark/timeobserver/lib/python2.7/site-packages/gspread/httpsession.py", line 71, in request
    response.status_code, response.content))

gspread latest (0.3.0)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 5
  • Comments: 31 (3 by maintainers)

Most upvoted comments

@kotborealis thanks for your fix, I’ve updated my comment too

I have tested the snippet and here is the final solution, that works for me (proxy class for worksheet):

class WKS:
    def __init__(self):
        scope = ['https://spreadsheets.google.com/feeds']
        self.credentials = ServiceAccountCredentials.from_json_keyfile_name(secret.GOOGLE_JSON_FILENAME, scope)
        self._refresh_auth()

    def _refresh_auth(self):
        gc = gspread.authorize(self.credentials)
        self.wks = gc.open_by_key(secret.SPREADSHEET_KEY).sheet1

    def _decorate(self, method):
        def safe_method(*args, **kwargs):
            try:
                method(*args, **kwargs)
            except gspread.exceptions.HTTPError as e:
                # getattr is needed to get a new instance of self.wks
                self._refresh_auth()
                # UPD: fix by @kotborealis
                return getattr(self.wks, method.__name__)(*args, **kwargs) 
        return safe_method

    def __getattr__(self, attr):  # doesn't shadow _refresh_auth and _decorate
        return self._decorate(getattr(self.wks, attr))