Python - Gspread Request Error 401

2024/9/20 11:53:44

I'm currently making a Discord-bot that connects to a Google-spreadsheet (gspread). But after I've been running it for a while it starts to hand out errors and it can't connect to my gspread anymore (unless i restart it).

The error that I'm receiving: (https://hastebin.com/odutucawuv.tex)

Ignoring exception in command sub
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 65, in sub
val = worksheet.cell(cell_name.row, cell_name.col+4)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 392, in cell
self._cell_addr(row, col))
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\client.py", line 210, in get_cells_cell_id_feed
r = self.session.get(url)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 73, in get
return self.request('GET', url, params=params, **kwargs)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 69, in request
response.status_code, response.content))
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'')The above exception was the direct cause of the following exception:Traceback (most recent call last):
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: 
RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'')
Ignoring exception in command add
Traceback (most recent call last):
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 130, in add
cell_name = worksheet.find(str(member))
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 711, in find
return self._finder(finditem, query)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 696, in _finder
cells = self._fetch_cells()
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 331, in _fetch_cells
feed = self.client.get_cells_feed(self)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\client.py", line 176, in get_cells_feed
r = self.session.get(url)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 73, in get
return self.request('GET', url, params=params, **kwargs)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 69, in request
response.status_code, response.content))
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'')During handling of the above exception, another exception occurred:Traceback (most recent call last):
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "C:\Users\simvid-5\Desktop\Pogomoves\DiscordBot.py", line 136, in add
cell_list = worksheet.range('A2:A100')
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 72, in wrapper
return method(self, *args, **kwargs)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\models.py", line 412, in range
params={'range': name, 'return-empty': 'true'}
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\client.py", line 176, in get_cells_feed
r = self.session.get(url)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 73, in get
return self.request('GET', url, params=params, **kwargs)
File "C:\Python36\lib\site-packages\gspread-0.6.2-
py3.6.egg\gspread\httpsession.py", line 69, in request
response.status_code, response.content))
gspread.exceptions.RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'')The above exception was the direct cause of the following exception:Traceback (most recent call last):
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Python36\lib\site-packages\discord.py-0.16.10-
py3.6.egg\discord\ext\commands\core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: 
RequestError: (401, '401: 
b\'<HTML>\\n<HEAD>\\n<TITLE>Unauthorized</TITLE>\\n</HEAD>\\n<BODY 
BGCOLOR="#FFFFFF" TEXT="#000000">\\n<H1>Unauthorized</H1>\\n<H2>Error 
401</H2>\\n</BODY>\\n</HTML>\\n\'')

And one of the functions that I'm using if it's to any help to understand the problem above, I can provide more of my code if it's necessary to fix it:

import discord
import asyncio
import random
import pickle
import os
import gspread
import timefrom oauth2client.service_account import ServiceAccountCredentials
from discord.ext import commandsprefix = '!'def returnPrefix():global prefixreturn prefixbot = commands.Bot(returnPrefix())scope = ['https://spreadsheets.google.com/feeds']
credentials = 
ServiceAccountCredentials.from_json_keyfile_name('GoogleSpreadsheetCreds.json', scope)
gc = gspread.authorize(credentials)
sh = gc.open("MyWorksheet")
worksheet = sh.sheet1@bot.event
async def on_ready():print('Logged in as')print(bot.user.name)print(bot.user.id)print('-----')await bot.change_presence(game=discord.Game(name='Stackoverflow'))@bot.command(pass_context=True)
@commands.has_role("Premium")
async def sub(ctx, member: discord.Member = None):global cell_nameif member is None:member = ctx.message.author#Delete user_command.await bot.delete_message(ctx.message)#Retrieve user from commander.Username = '{0}'.format(member)try:#Try to find the username in spreadsheet.cell_name = worksheet.find(Username)except: #If we dont find the username.await bot.say("Your name ("+Username+") was not found, please contact someone for help.")if cell_name.value == Username: #If we find the username.#Retrieve some values.val = worksheet.cell(cell_name.row, cell_name.col+4)val_date = worksheet.cell(cell_name.row, cell_name.col+3)remaining_days = val.valueremaining_date = val_date.value#Send a message to a member.await bot.send_message(member,"```Username: "+ Username+"\nRemaining days: "+remaining_days+"\nDate for expiration: "+remaining_date+"```")
Answer

Your access token expires after some period of time. From the OAuth 2.0 docs:

  1. Refresh the access token, if necessary.

Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

Note: Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.

I don't believe that gspread is equipped to deal with refresh tokens. You may just be able to catch this exception and reauthenticate as needed.

EDIT:

After looking at the gspread source I think you may be able to refresh your token by simply calling gc.login()

EDIT:

This issue was filed with gspread a couple of years ago but it was closed for no apparent reason. Here is one approach to solving it:

def add_row(row):try:gs_client = gspread.authorize(creds)gs_worksheet = gs_client.open("foo").sheet1if creds.access_token_expired:gs_client.login()  # refreshes the tokengs_worksheet.append_row(row)except Exception, e:traceback.print_exc()

but I think that's overkill. You should be able to just call gc.login() right before your try: block:

gc.login()
try:#Try to find the username in spreadsheet.cell_name = worksheet.find(Username)
except: #If we dont find the username.
https://en.xdnf.cn/q/72177.html

Related Q&A

paramiko server mode port forwarding

I need to implement a ssh server using paramiko that only handles -R port forwarding requests like this:ssh -N -T -R 40005:destination_host:22 [email protected]So far from what i understand ill have to…

Pandas dataframe.hist() change title size on subplot?

I am manipulating DataFrame using pandas, Python. My data is 10000(rows) X 20(columns) and I am visualizing it, like this.df.hist(figsize=(150,150))However, if I make figsize bigger, each of subplots t…

Regex match back to a period or start of string

Id like to match a word, then get everything before it up to the first occurance of a period or the start of the string. For example, given this string and searching for the word "regex":s = …

Finding differences between strings

I have the following function that gets a source and a modified strings, and bolds the changed words in it.def appendBoldChanges(s1, s2):"Adds <b></b> tags to words that are changed&qu…

Python pandas: select 2nd smallest value in groupby

I have an example DataFrame like the following:import pandas as pd import numpy as np df = pd.DataFrame({ID:[1,2,2,2,3,3,], date:array([2000-01-01,2002-01-01,2010-01-01,2003-01-01,2004-01-01,2008-01-01…

How to disable SSL3 and weak ciphers with cherrypy builtin ssl module (python 3)

I have configured Cherrypy 3.8.0 with Python 3 to use SSL/TLS. However, I want to disable SSL3 to avoid POODLE. I searched through the documentation but I am unsure on how to implement it.I am using th…

cleaning big data using python

I have to clean a input data file in python. Due to typo error, the datafield may have strings instead of numbers. I would like to identify all fields which are a string and fill these with NaN using p…

Using the Python shell in Vi mode on Windows

I know that you can use the Python shell in Vi mode on Unix-like operating systems. For example, I have this line in my ~/.inputrc:set editing-mode viThis lets me use Vi-style editing inside the Python…

Calculate residual deviance from scikit-learn logistic regression model

Is there any way to calculate residual deviance of a scikit-learn logistic regression model? This is a standard output from R model summaries, but I couldnt find it any of sklearns documentation.

Use Python to create 2D coordinate

I am truly a novice in Python. Now, I am doing a project which involves creating a list of 2D coordinates. The coordinates should be uniformly placed, using a square grid (10*10), like(0,0)(0,1)(0,2)(0…