首页 > 解决方案 > 尝试刷新令牌时出现 python 错误的 Google API

问题描述

所以我试图在 python 3.8.5 中编写这个程序,它与谷歌电子表格交互,但是当令牌过期时,我不知道如何刷新它。

我的代码几乎是从https://developers.google.com/sheets/api/quickstart/python复制而来的:

from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials

def service_spread():
    """
    Creates token for spreadsheet with required authorisation.
    Returns required service.
    """
    SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token_spread.json'):
        creds = Credentials.from_authorized_user_file('token_spread.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token_spread.json', 'w') as token:
            token.write(creds.to_json())

    return build('sheets', 'v4', credentials=creds)

如果没有令牌,它就像一个魅力。如果有令牌并且它已过期,则会引发以下错误:

RefreshError                              Traceback (most recent call last)
<ipython-input-6-63b097a471a1> in <module>
----> 1 service = service_spread()

<ipython-input-5-12e029dbbb2f> in service_spread()
     14     if not creds or not creds.valid:
     15         if creds and creds.expired and creds.refresh_token:
---> 16             creds.refresh(Request())
     17         else:
     18             flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)

~\anaconda3\lib\site-packages\google\oauth2\credentials.py in refresh(self, request)
    206         scopes = self._scopes if self._scopes is not None else self._default_scopes
    207 
--> 208         access_token, refresh_token, expiry, grant_response = _client.refresh_grant(
    209             request,
    210             self._token_uri,

~\anaconda3\lib\site-packages\google\oauth2\_client.py in refresh_grant(request, token_uri, refresh_token, client_id, client_secret, scopes)
    246         body["scope"] = " ".join(scopes)
    247 
--> 248     response_data = _token_endpoint_request(request, token_uri, body)
    249 
    250     try:

~\anaconda3\lib\site-packages\google\oauth2\_client.py in _token_endpoint_request(request, token_uri, body)
    122                 retry += 1
    123                 continue
--> 124             _handle_error_response(response_body)
    125 
    126     return response_data

~\anaconda3\lib\site-packages\google\oauth2\_client.py in _handle_error_response(response_body)
     58         error_details = response_body
     59 
---> 60     raise exceptions.RefreshError(error_details, response_body)
     61 
     62 

RefreshError: ('invalid_scope: Bad Request', '{\n  "error": "invalid_scope",\n  "error_description": "Bad Request"\n}')

我已经在互联网上搜索过,但我不知道如何解决它。有人可以帮我吗?我需要这段代码在无人监督的情况下运行,所以我需要自动刷新令牌,而不需要任何人为干预。

标签: google-apigoogle-oauthgoogle-sheets-apipython-3.8google-api-python-client

解决方案


推荐阅读