“使用google-auth和gspread时,'凭据'对象没有属性'access_token'”

问题描述 投票:2回答:3

我想使用gspread模块从Python编辑Google表格。 setup instructions包含以下示例:

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)

然而,根据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)

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

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

如果我进入调试器,我确实看到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']

Credentials生成的google-authoauth2client生成的gspread不同吗?

python google-api google-authentication oauth2client
3个回答
2
投票

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

如果您不想使用不推荐使用的oauthclient2,可能的workaroud是使用gspread.Client来利用here类的session参数。关于如何做这个access_token有一个很好的教程。


0
投票

作为band-aide修复,您可以创建一个继承凭据的新类,并添加一个新的gspread.authorize属性,该属性镜像凭证中的令牌。然后把它传递到#Create the new class 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, '[email protected]', perm_type='user', role='writer' ) 它应该工作。

token

0
投票

汤姆的乐队援助修复对我没有用,因为None最初是在Google OAuth2库中的import gspread import google.auth.transport.requests from google.oauth2 import service_account from oauth2client.service_account import ServiceAccountCredentials class OAuth2ServiceAccountFromGoogleOAuth2(ServiceAccountCredentials): # Hack based upon https://stackoverflow.com/questions/51618127/credentials-object-has-no-attribute-access-token-when-using-google-auth-wi def __init__(self, google_oauth2_credentials): self.google_oauth2_credentials = google_oauth2_credentials self.access_token = google_oauth2_credentials.token def refresh(self, http): if self.access_token is None: request = google.auth.transport.requests.Request() self.google_oauth2_credentials.refresh(request) self.access_token = self.google_oauth2_credentials.token #end if print(f'access token in {self.access_token}') #end def #end class with open("credentials.json") as gs_key_file: google_credentials = service_account.Credentials.from_service_account_info(json.loads(gs_key_file.read()), scopes=['https://www.googleapis.com/auth/spreadsheets']) gclient = gspread.authorize(OAuth2ServiceAccountFromGoogleOAuth2(google_credentials)) 。这是我的乐队援助修复:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.