Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"'Credentials' object has no attribute 'access_token'" when using google-auth with gspread

I'd like to use gspread module to edit Google sheets from Python. The setup instructions contain the following example:

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)

However, according to https://pypi.org/project/oauth2client/ the oauth2client library is deprecated. So I've tried to adapt this as follows, using 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)

Unfortunately, I'm running into the following error:

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

If I drop into the debugger, I indeed see that credentials has a token attribute, but not an access_token one:

> /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']

Are the Credentials generated by google-auth not the same objects as the ones generated by oauth2client?

like image 875
Kurt Peek Avatar asked Dec 24 '22 05:12

Kurt Peek


1 Answers

As per the gspread documentation, the gspread.authorize method only supports credential objects that are created by the oauth2client library. To work with the new google-auth one, gspread should add support for it.

A possible workaroud, if you don't want to use the oauthclient2 that is deprecated, is to use authlib leveraging the session parameter of the gspread.Client class. There is a nice tutorial on how to do this here.

Update April 27 2020

Starting from version 3.4.0 gspread is now supporting google-auth. You can find all the details in the dedicated documentation. Here is an official statement from the author:

Older versions of gspread have used oauth2client. Google has deprecated it in favor of google-auth. If you’re still using oauth2client credentials, the library will convert these to google-auth for you, but you can change your code to use the new credentials to make sure nothing breaks in the future.

like image 90
Lorenzo Persichetti Avatar answered Dec 25 '22 18:12

Lorenzo Persichetti