2

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.

Outis Nemo
  • 127
  • 5
  • "Token has been expired or revoked." Seems pretty clear to me. Looks like they *don't want you* to keep using the same access token past a certain point. – Karl Knechtel Apr 13 '23 at 15:15
  • But the error seems to be upon refreshing; I'm assuming that it's refreshing the token every time I run it, so why does it only start failing after 1-2 weeks? In any case it's certainly not clear to me at all what's going on or what the problem is. – Outis Nemo Apr 13 '23 at 16:01

1 Answers1

2

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:

Daniel
  • 3,157
  • 2
  • 7
  • 15
  • Based on the error, this seems like it fits; it seems like it's clearly refreshing, and it's certainly uploading for a lot longer than 1 hour. As for the 7 day limit you quote there, I think I remember something about setting up the projecting as "Testing"; there's nothing in the code itself that indicates this, but I believe it was on one of those arcane subpages I mentioned above, which I found mazelike and extremely hard to navigate in a meaningful way (I almost considered it a miracle when I got it to work in the first place). Where exactly do I find these "OAuth consent screen settings"? – Outis Nemo Apr 13 '23 at 18:10
  • Actually, I believe I found it based on that. Where it says "Testing", the alternative is "Publish app", which I assume is necessary to change it to "In production"; however, when I try to do that it says: " An official link to your app's Privacy Policy A YouTube video showing how you plan to use the Google user data you get from scopes A written explanation telling Google why you need access to sensitive and/or restricted user data All your domains verified in Google Search Console" This sounds rather ridiculous, because I'm the only one using this thing. – Outis Nemo Apr 13 '23 at 18:14
  • Digging further, I found this: " Personal Use: The app is not shared with anyone else or will be used by fewer than 100 users (all of whom are known personally to you). Note that your app will be subject to the unverified app screen and the 100-user cap will be in effect." This seems like a fit for my app, and that it would make me exempt from all the above hassle; apparently I could simply change it and leave it as unverified with a 100-person cap. That should fix my problem. Thanks for pointing me in the right way. – Outis Nemo Apr 13 '23 at 18:20
  • 1
    That's good to hear. Just as an aside, since your app is also just for personal use you could also have ignored the YouTube video and written explanation requirements after publishing. This is known as [OAuth verification](https://support.google.com/cloud/answer/9110914?hl=en#zippy=%2Cwhat-happens-if-i-dont-submit-my-app-for-review), but not doing it just adds a warning before authorizing your app and the same 100 user limit. Since It's your own app you can just ignore the warning and move on. – Daniel Apr 13 '23 at 19:04
  • Yes, that's what I meant that I ended up doing. – Outis Nemo Apr 14 '23 at 07:29