Closed Klikovskiy closed 1 year ago
To be exact every 2 weeks u have to update the token. If ur app in Test Mode, u cannot bypass this thing. Only in production mode its possible to make a forever token :)
Actually, there are valid reasons for which a refresh token could be revoked even in production. The documentation from Google lists a few
To me the problem is in this area of the pygsheet code. The line credentials.refresh(Request())
can throw these two errors by example:
google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', {'error': 'invalid_grant', 'error_description': 'Bad Request'})
google.auth.exceptions.RefreshError: ('deleted_client: The OAuth client was deleted.', {'error': 'deleted_client', 'error_description': 'The OAuth client was deleted.'})
In the meantime, I'm now instantiating pygheets using this piece of code:
from google.auth.exceptions import RefreshError
def gclient():
try:
return pygsheets.authorize(client_secret="client_secret.json", local=True)
except RefreshError:
credentials_filename = 'sheets.googleapis.com-python.json'
if os.path.exists(credentials_filename):
os.remove(credentials_filename)
return pygsheets.authorize(client_secret="client_secret.json", local=True)
I think that you could fix it for good in pygsheets in the following way:
def get_new_credentials(client_secret_file, scopes, local=False):
if local:
flow = InstalledAppFlow.from_client_secrets_file(client_secret_file, scopes)
return flow.run_local_server()
else:
flow = Flow.from_client_secrets_file(client_secret_file, scopes=scopes,
redirect_uri='urn:ietf:wg:oauth:2.0:oob')
auth_url, _ = flow.authorization_url(prompt='consent')
print('Please go to this URL and finish the authentication flow: {}'.format(auth_url))
code = input('Enter the authorization code: ')
flow.fetch_token(code=code)
return flow.credentials
def _get_user_authentication_credentials(client_secret_file, scopes, credential_directory=None, local=False):
credentials = None
if os.path.exists(credentials_path):
# expect these to be valid. may expire at some point, but should be refreshed by google api client...
credentials = Credentials.from_authorized_user_file(credentials_path, scopes=scopes)
if credentials:
if credentials.expired and credentials.refresh_token:
try:
credentials.refresh(Request())
except RefreshError:
os.remove(credentials_path)
credentials = get_new_credentials(client_secret_file, scopes, local)
else:
credentials = get_new_credentials(client_secret_file, scopes, local)
Do you agree? Can I make a PR for this?
@flavianh Sounds good, you can make a PR with this.
Hello! How can I disable frequent refresh of the Token? Quite often, you have to renew the token for the errors “Token has been expired or revoked.”