малиновый пи-питон, большая ошибка OAuth 2 - PullRequest
0 голосов
/ 25 мая 2018

У меня есть скрипт, который должен добавлять строку в таблицу Google каждые 2 минуты.Когда я запускаю скрипт, он работает хорошо, но через некоторое время я получаю следующую ошибку:

{
  "error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

Python Script

import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']

credentials = ServiceAccountCredentials.from_json_keyfile_name('auth.json', scope)
gc = gspread.authorize(credentials)

wks = gc.open('sheet').sheet1

while True:
    #here is some other code and 2 minutes delay
    wks.append_row(["test", "test2"])

Auth.json

{
  "type": "x",
  "project_id": "x",
  "private_key_id": "x",
  "private_key": "x",
  "client_email": "x",
  "client_id": "x",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "x"
}

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Время ожидания аутентификационного токена НЕ соответствует моему опыту - иногда это ровно час, но иногда оно может быть значительно больше (например, несколько часов) или значительно меньше.

У меня есть проект, который отправляетданные в Google Sheets каждую минуту через учетную запись службы.Когда я впервые запустил его, мой сценарий был организован как сценарий KT Work с первоначальной авторизацией входа вне основного цикла.Излишне говорить, что я начал сталкиваться с ошибками 401 НЕСАНКЦИОНИРОВАННО, как и все остальные.

Поэтому я добавил дополнительный gc.login () в основной цикл со счетчиком, чтобы запускать его каждые 45 минут.Я по-прежнему сталкивался с 401 НЕСАНКЦИОНИРОВАННЫМИ сбоями, поэтому я уменьшил его до 30 минут, затем до 20 минут, затем даже до 10 минут, но я все равно видел бы ту же ошибку, по крайней мере, один раз в день, а иногда и больше.

Наконец-то я избавился от счетчика и просто начал выполнять gc.login () на каждой итерации цикла, т. Е. Каждую минуту.Хотя это, как правило, решает 401 НЕСАНКЦИОНИРОВАННЫХ ошибок, это не панацея!Зачем?Потому что теперь я вижу случайные 503 недоступные ошибки, которые имеют тот же эффект остановки сценария.

Так что же является окончательным решением?Добавление простого сторожевого сценария, который выполняет основной сценарий, а затем перезапускает его в случае сбоя.Я попробовал несколько примеров, но я остановился на простом, элегантном, с которым я столкнулся несколько месяцев назад:

[https://www.alexkras.com/how-to-restart-python-script-after-exception-and-run-it-forever/]

Так что я настроил свой собственный "RunScriptForeverWatchdog.py""скрипт выглядит следующим образом:

#!/usr/bin/python
from subprocess import Popen
import sys

filename = sys.argv[1]
while True:
    print("\n(Re-)Starting script:  " + filename)
    p = Popen("python " + filename, shell=True)
    p.wait()

Теперь я просто выполняю этот сторожевой скрипт с основным скриптом в качестве аргумента, и каждый раз, когда последний терпит неудачу, он немедленно возрождается первым.

0 голосов
/ 22 июня 2018

Токен, выпущенный Google, является токеном с коротким сроком действия, срок действия которого истекает через короткое время.ServiceAccountCredentials имеет метод refresh для получения нового токена.В вашем случае, поскольку он вызывается каждые 2 минуты, вы можете звонить gc.login() каждые 2 минуты.

while True:
    gc.login()

Я не уверен, почему он не обновляется сам по себе (он должен).К вашему сведению, oauth2client устарел, подумайте об использовании других вещей.Вот совет о том, как использовать его с Authlib: https://blog.authlib.org/2018/authlib-for-gspread

...