Python &引用';证书';对象没有属性';访问令牌'&引用;将google auth与gspread一起使用时

Python &引用';证书';对象没有属性';访问令牌'&引用;将google auth与gspread一起使用时,python,google-api,google-authentication,oauth2client,Python,Google Api,Google Authentication,Oauth2client,我想使用模块从Python编辑Google工作表。文件包含以下示例: import gspread from oauth2client.service_account import ServiceAccountCredentials scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] credentials = ServiceAccountCre

我想使用模块从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)
但是,根据
oauth2client
的说法,库是不推荐使用的。因此,我尝试使用以下方法对其进行调整:

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

(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'

google auth
生成的
凭据是否与由
oauth2client
生成的对象不同?

根据
gspread
文档,该方法仅支持由创建的凭据对象。要使用新的,gspread应该添加对它的支持

如果您不想使用不推荐使用的oauthclient2,一种可能的解决方法是利用类的session参数。关于如何做到这一点,有一个很好的教程

更新日期:2020年4月27日 从gspread开始,它现在支持。您可以在中找到所有详细信息。以下是作者的官方声明:

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


作为band aide修复程序,您可以创建一个继承凭据的新类,并添加一个新的
access\u token
属性,以镜像凭据中的令牌。然后将其传递到
gspread.authorize
中,它应该可以工作

# create the new class to fix credentials
class fixed_creds(service_account.Credentials):
    def __init__(self, creds):
        self.access_token = creds.token

# create new credential object with the access_token
gcreds = fixed_creds(credentials)

# pass new credentials into gspread
sheets = gspread.authorize(gcreds)

# create a new sheet to test it
new_sheet = sheets.create('TestSheet')

# give yourself permission to see the new sheet
sheets.insert_permission(
    new_sheet.id,
    'youremail@yourdomain.com',
    perm_type='user',
    role='writer'
)

汤姆的创可贴对我不起作用,因为
token
最初是
None
在谷歌OAuth2库中。这是我的创可贴:

导入gspread
导入google.auth.transport.requests
从google.oauth2导入服务_帐户
从oauth2client.service\u帐户导入ServiceAccountCredentials
类OAuth2ServiceAccountFromGoogleOAuth2(ServiceAccountCredentials):#基于https://stackoverflow.com/questions/51618127/credentials-object-has-no-attribute-access-token-when-using-google-auth-wi
定义初始化(self,google\u oauth2\u凭证):
self.google\u oauth2\u凭证=google\u oauth2\u凭证
self.access\u token=google\u oauth2\u credentials.token
def刷新(自我,http):
如果self.access_令牌为无:
request=google.auth.transport.requests.request()
self.google\u oauth2\u凭据。刷新(请求)
self.access\u token=self.google\u oauth2\u credentials.token
#如果结束
打印(f'access token in{self.access_token}')
#结束定义
#末级
打开(“credentials.json”)作为gs_key_文件:
google\u credentials=service\u account.credentials.from\u service\u account\u info(json.loads(gs\u key\u file.read()),scopes=['https://www.googleapis.com/auth/spreadsheets'])
gclient=gspread.authorize(OAuth2ServiceAccountFromGoogleOAuth2(google_凭证))

一年半后,在同样的情况下,我发现这对我来说是可行的:

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)

该解决方案改编自gspread github和
googleauth

自从这篇文章发表后,GSpread增加了对新的googleauth凭证的访问:@Alec是正确的。gspread从3.4.0版开始就一直在使用google auth。@Burnash和Alec(Stackoverflow只允许我有一个标签)感谢您指出这条新闻。我已经相应地更新了我的答案,让我知道它对您是否合适。它也对我用google.oauth2替换oauth2client的使用起到了作用。谢谢
# create the new class to fix credentials
class fixed_creds(service_account.Credentials):
    def __init__(self, creds):
        self.access_token = creds.token

# create new credential object with the access_token
gcreds = fixed_creds(credentials)

# pass new credentials into gspread
sheets = gspread.authorize(gcreds)

# create a new sheet to test it
new_sheet = sheets.create('TestSheet')

# give yourself permission to see the new sheet
sheets.insert_permission(
    new_sheet.id,
    'youremail@yourdomain.com',
    perm_type='user',
    role='writer'
)
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)