将 google-auth 与 gspread 一起使用时,“'Credentials' 对象没有属性'access_token'”

Kur*_*eek 4 python google-api google-authentication oauth2client

我想使用gspread模块从 Python 编辑 Google 表格。的设置说明包含下面的例子:

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('gspread-april-2cd … ba4.json', scope)

gc = gspread.authorize(credentials)
Run Code Online (Sandbox Code Playgroud)

但是,根据https://pypi.org/project/oauth2client/,oauth2client库已被弃用。所以我尝试将其调整如下,使用google-auth

import gspread
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file(
    'my_client_secrets.json')

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/spreadsheets'])

gc = gspread.authorize(scoped_credentials)
Run Code Online (Sandbox Code Playgroud)

不幸的是,我遇到了以下错误:

(lucy-web-CVxkrCFK) bash-3.2$ python nps.py
Traceback (most recent call last):
  File "nps.py", line 54, in <module>
    gc = gspread.authorize(scoped_credentials)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/gspread/__init__.py", line 38, in authorize
    client.login()
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/gspread/client.py", line 46, in login
    if not self.auth.access_token or \
AttributeError: 'Credentials' object has no attribute 'access_token'
Run Code Online (Sandbox Code Playgroud)

如果我进入调试器,我确实看到它credentials有一个token属性,但不是access_token一个:

> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/scripts/nps.py(54)<module>()
     53 import ipdb; ipdb.set_trace()
---> 54 gc = gspread.authorize(scoped_credentials)
     55 

ipdb> type(credentials)
<class 'google.oauth2.service_account.Credentials'>
ipdb> type(scoped_credentials)
<class 'google.oauth2.service_account.Credentials'>
ipdb> dir(credentials)
['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_additional_claims', '_from_signer_and_info', '_make_authorization_grant_assertion', '_project_id', '_scopes', '_service_account_email', '_signer', '_subject', '_token_uri', 'apply', 'before_request', 'expired', 'expiry', 'from_service_account_file', 'from_service_account_info', 'has_scopes', 'project_id', 'refresh', 'requires_scopes', 'scopes', 'service_account_email', 'sign_bytes', 'signer', 'signer_email', 'token', 'valid', 'with_claims', 'with_scopes', 'with_subject']
Run Code Online (Sandbox Code Playgroud)

Credentials通过产生google-auth不一样的物体通过所产生的那些oauth2client

Lor*_*tti 5

根据gspread文档,gspread.authorize方法仅支持由oauth2client 库创建的凭证对象。要使用新的google-auth,gspread 应该添加对它的支持。

如果您不想使用已弃用的 oauthclient2,一个可能的解决方法是使用authlib,利用gspread.Client类的会话参数。这里是如何做到这一点一个很好的教程在这里

2020 年 4 月 27 日更新

3.4.0 版开始gspread 现在支持google-auth。您可以在专用文档中找到所有详细信息。以下是作者的官方声明:

旧版本的 gspread 使用oauth2client。谷歌已弃用它而支持 google-auth。如果您仍在使用 oauth2client 凭据,库会为您将这些凭据转换为 google-auth,但您可以更改代码以使用新凭据,以确保将来不会发生任何中断。

  • 自发布以来,GSpread 添加了对新 google-auth 凭据的访问:https://gspread.readthedocs.io/en/latest/oauth2.html (2认同)

Rol*_*Bly 5

一年半后,在完全相同的情况下,我发现这对我有用:

import gspread
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession

credentials = service_account.Credentials.from_service_account_file(
    'your_key_file.json')

scoped_credentials = credentials.with_scopes(
        ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
        )

gc = gspread.Client(auth=scoped_credentials)
gc.session = AuthorizedSession(scoped_credentials)
sheet = gc.open_by_key('key_in_sharelink')
print(sheet.title)
Run Code Online (Sandbox Code Playgroud)

解决方案改编自gspread github 中的这篇文章google-auth 用户指南