pythonauthenticationgoogle-drive-apicredentialspydrive

Why does PyDrive stop refreshing the access token after a while?


I'm using PyDrive to regularly upload something to my Drive (every ~15 minutes or so), but after a while (I haven't checked exactly, I believe it's a week or two) it stops uploading anything, yielding instead this error message:

pydrive2.auth.RefreshError: Access token refresh failed: invalid_grant: Token has been expired or revoked.

Now, granted, to set this up I had to go through a whole lot of extremely arcane subpages of Google that I did not understand very much of (I have a computer engineering background, but maybe I'm just not supposed to understand this web stuff), so it's no surprise that something isn't working right; I just have no idea what it is.

In my project folder where the script doing the uploading is located I have a client_secrets.json file that remains the same, and whenever it stops refreshing my access token I have to delete the credentials.json file, run the script again, and manually authenticate via a browser; after doing this it happily uploads for another 1-2 weeks before I have to do it again.


Solution

  • The access tokens used to gain access to your Drive only have a lifetime of 1 hour. After that, you need to reauthorize the app, or if your application also requested a refresh token, you can use this refresh token to request a new access token.

    Refresh tokens have an indefinite lifetime, so once you have one, it is possible to keep using it "forever" to get new access tokens, but there are various situations that can invalidate them. You can find these in the documentation. Based on your description of the issue, I'm guessing the most likely cause is this one:

    A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.

    Can't know for sure without seeing your code, but most likely it first requests an access and refresh token, then it keeps using the refresh token afterwards. When the token expires after 7 days it finds out that it has been revoked and throws an error. After the token is revoked, the only way to get a new one is to manually authenticate again.

    The solution would be to check your OAuth consent screen settings and make sure that the status is set to "In production".

    If this is not the cause, then it could be that your app always requests a new refresh token, but keeps using only the first one. There's a limit of 100 tokens per client ID, so the oldest token gets invalidated after reaching this limit, or maybe you are somehow revoking the app's access. Most likely it's the project status, so check that first.

    References: