mirror of
https://github.com/spotipy-dev/spotipy.git
synced 2026-04-27 00:25:54 +03:00
[GH-ISSUE #766] GET /me/player + 429 Rate Limit exceeded = blocking calls #468
Labels
No labels
api-bug
bug
dependencies
documentation
duplicate
enhancement
external-ide
headless-mode
implicit-grant-flow
invalid
missing-endpoint
pr-welcome
private-api
pull-request
question
spotipy3
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/spotipy#468
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @gorenje on GitHub (Jan 4, 2022).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/766
Describe the bug
Currently my API limit is used up so I'm constantly getting API rate limit exceeded (error code 429) from the Spotify API. Which means that spotipy is doing a lot of request retrying. However this causes calls to block and hang because Spotify is setting
the
retry_afterheader to 3600. The retry_after header is respected by the urllib3 (I assume) and it's waiting for an hour to retry the call.I've set the request_timeout option to 5 (i.e. 5 seconds) and retries to 3 but the very first retry will block. So the only fix at the moment is to set retries to zero. Then the call will fail immediately.
Your code
spoitpy.Spotify().current_playback() # <--- this hangs/blocks for an hour....
Expected behavior
I would expect that request_timeout would be respected and the call would timeout after request_timeout seconds. Then a second retry would be made that would also fail after request_timeout ... etc.
Output
No ouptut, call hangs/blocks.
Environment:
My point is that this was unexpected behaviour and I initially assumed that Spotify was having an issue. The only thing I was seeing was that my calls to current_playback were hanging and blocking my code. Then I came to discover that spotipy does automagical retries. And then I realised there was a retry_after header ...
So the end result was that Spotify killed my application my setting a header that spotipy blindly respects even though that an hour is far more that than the request_timeout value set in spotipy. I guess it would be nice if the default settings of spotipy would be more obvious when a API rate limit is hit - I only found out that I had a rate limit issue by doing a corresponding curl request.
@gorenje commented on GitHub (Jan 4, 2022):
Besides setting retries=0, another fix is to add
respect_retry_after_header=Falseat about this point - i.e. disable urllib3 from respecting the header.I'm all for services provide feedback about rate limits but these should also be communicated to the end user. So I would find it a better solution not to retry on 429 error codes and instead fail. Rate limits only get worse with constant retrying ....
@Peter-Schorn commented on GitHub (Jan 4, 2022):
The entire requests library uses blocking APIs. The thread is blocked during network requests as well; requests does not support async. The retry delay is just generally longer than the delay between making a network request and receiving a response, so it's more noticable.
Presumably, the
request_timeoutparameter refers to how long the library will wait for a response from the server after making each network request and does not factor in the retry delay. This is an issue you'll have to address with the developers of the requests library, not spotipy.@gorenje commented on GitHub (Jan 4, 2022):
True that since the
request_timeoutvalue is passed onto the urllib3 client.However urllib3 does offer the possibility of deactivating the
retry_afterheader. So the spotipy library could support that option and pass the option up to the user of spotipy (as part of the initialization of the client).Guess what I found confusing was that my call to
current_playback()simply froze and it would have continued to stay frozen for an hour, since theretry_aftervalue was 3600. And it did that simply out of the blue (ok, I'd been hitting the Spotify API too often and Spotify decided enough was enough)!On the other hand, I didn't know I was hitting rate limits since spotipy was retrying for me. My workaround now is to have
retries=0and instead deal with exceptions when my rate limit is reached. I'd rather know when I've reached my rate limit than have my calls to Spotify simply freeze and block the rest of my code. I understand spotipy does automagical retries because theretry_aftervalue is generally low (i.e. 1 or 2 seconds) but when it becomes extreme, this can become painful.@Peter-Schorn commented on GitHub (Jan 4, 2022):
The
Spotifyinitializer does have a parameter for the number of retries, so you can set that to 0 to disable any retries. For more customization, you can create a customrequests.Session, customize the retry policy, and pass that into theSpotifyinitializer instead. Using this method, you can ignore the retry-after header:@gorenje commented on GitHub (Jan 4, 2022):
Of course! I noticed the
requests_sessionparameter but didn't think of rolling my own! 👍I would go back to 3 retries but simply ignore the retry_after header.
Cheers and thanks for the heads-up!
@CalColistra commented on GitHub (Apr 6, 2023):
Hi, I have been running into a similar (if not the same) issue. When I try to get spotify data about an artist by using their artist() function, it gets stuck in the sleep_for_retry() function and it does not tell me how to to sleep for.
Here is my code for getting data for an artist:
currentResults = spotify.artist(<artist id>)for more details about my original problem, I previously created a issue that was closed here: issue #956
I just tried the solution from @Peter-Schorn here in this issue and I can't figure out how to get it working or if that would even solve my sleep_for_retry() problem.
I created a session like this, *note my spotipy.Spotify() function wouldn't work unless I added my client_id and redirect_uri within the auth_manager:
After that I try making a request to get data about an artist like so:
currentResults = spotify.artist(<artist id>)But I get this error that seems like there is a problem getting my access token:
I tried passing my access token in the original auth_manager as different parameters such as 'client_secret' or 'code' as it shows in the error message but had no luck. Does anyone have an advice or tips for me?
@Peter-Schorn commented on GitHub (Apr 18, 2023):
The Access token, client id, and authorization code are all different things.
Try providing a non-empty authorize scope string.