2017-08-28 3 views
0

Je crée actuellement un Discord-bot qui se connecte à une feuille de calcul Google (gspread). Mais après l'avoir exécuté pendant un moment, il commence à distribuer des erreurs et il ne peut plus se connecter à mon gspread (sauf si je le redémarre).Python - Gspread Request Error 401

L'erreur que je reçois: (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\'') 

Et l'une des fonctions que j'utilise si elle est à toute aide à comprendre le problème ci-dessus, je peux fournir plus de mon code s'il est nécessaire de le réparer:

import discord 
import asyncio 
import random 
import pickle 
import os 
import gspread 
import time 

from oauth2client.service_account import ServiceAccountCredentials 
from discord.ext import commands 

prefix = '!' 

def returnPrefix(): 
    global prefix 
    return prefix 

bot = 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_name 
    if 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.value 
     remaining_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+"```") 

Répondre

1

Votre jeton d'accès expire après un certain temps. De l'OAuth 2.0 docs:

  1. Actualiser le jeton d'accès, le cas échéant.

Les jetons d'accès ont des durées de vie limitées. Si votre application a besoin d'accéder à une API Google au-delà de la durée de vie d'un jeton d'accès unique, elle peut obtenir un jeton d'actualisation. Un jeton d'actualisation permet à votre application d'obtenir de nouveaux jetons d'accès.

Remarque: enregistrez les jetons d'actualisation dans un stockage sécurisé à long terme et continuez à les utiliser tant qu'ils restent valides. Les limites s'appliquent au nombre de jetons d'actualisation émis par combinaison client-utilisateur et par utilisateur sur tous les clients, et ces limites sont différentes. Si votre application demande suffisamment de jetons d'actualisation pour dépasser l'une des limites, les anciens jetons d'actualisation cessent de fonctionner.

Je ne crois pas que gspread soit équipé pour traiter des jetons d'actualisation. Vous pouvez juste être en mesure d'attraper cette exception et de réauthentifier au besoin.

EDIT:

Après avoir regardé la source gspread Je pense que vous peut être en mesure de rafraîchir votre jeton en appelant simplement gc.login()

EDIT:

Cette issue a été déposé auprès gspread un couple il y a des années, mais il a été fermé sans raison apparente. Voici one approach à résoudre:

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

mais je pense que c'est surpuissant. Vous devriez pouvoir simplement appeler gc.login() juste avant votre bloc try::

gc.login() 
try: 
    #Try to find the username in spreadsheet. 
    cell_name = worksheet.find(Username) 
except: #If we dont find the username. 
+0

Merci, je vais essayer ça! Donc, pas d'entrées nécessaires pour gc.login()? – Simvid

+0

Juste, pas d'arguments. Vous devez l'appeler _après_ que le jeton d'accès expire. – Jeff

+0

Merci, cela a fonctionné! – Simvid

0

Le seul coupable plausible ici est vos informations d'identification de compte. Essayez de créer de nouvelles informations d'identification sur votre console pour développeur Google et de l'utiliser.

+0

Essayer cela aussi! merci – Simvid