Print warnings when a rate/request limit is reached (#1134)

* create custom urllib3.Retry class for printing warnings on rate/request limits

* move import urllib3 from client.py to util.py

* Using Retry.increment instead of Retry.is_retry. Shows the Retry-After value in the warning as well

* Making sure that max column <= 99

* add types.TracebackType

* Change warning in request/rate limit warning

* adding all parameters, just to make sure

* fixing length of line

* making sure that response is not None
This commit is contained in:
Niko 2024-06-25 09:26:19 +02:00 committed by GitHub
parent 5e09c78ccf
commit 66ad716595
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 2 deletions

View File

@ -15,6 +15,7 @@ Add your changes below.
- Updated TUTORIAL.md instructions to match current layout of Spotify Developer Dashboard - Updated TUTORIAL.md instructions to match current layout of Spotify Developer Dashboard
- Added test_artist_id, test_artist_url, and test_artists_mixed_ids to non_user_endpoints test.py - Added test_artist_id, test_artist_url, and test_artists_mixed_ids to non_user_endpoints test.py
- Added rate/request limit to FAQ - Added rate/request limit to FAQ
- Added custom `urllib3.Retry` class for printing a warning when a rate/request limit is reached.
### Fixed ### Fixed
- Audiobook integration tests - Audiobook integration tests

View File

@ -8,9 +8,9 @@ import re
import warnings import warnings
import requests import requests
import urllib3
from spotipy.exceptions import SpotifyException from spotipy.exceptions import SpotifyException
from spotipy.util import Retry
from collections import defaultdict from collections import defaultdict
@ -220,7 +220,7 @@ class Spotify:
def _build_session(self): def _build_session(self):
self._session = requests.Session() self._session = requests.Session()
retry = urllib3.Retry( retry = Retry(
total=self.retries, total=self.retries,
connect=None, connect=None,
read=False, read=False,

View File

@ -1,3 +1,5 @@
from __future__ import annotations
""" Shows a user's playlists. This needs to be authenticated via OAuth. """ """ Shows a user's playlists. This needs to be authenticated via OAuth. """
__all__ = ["CLIENT_CREDS_ENV_VARS", "prompt_for_user_token"] __all__ = ["CLIENT_CREDS_ENV_VARS", "prompt_for_user_token"]
@ -5,9 +7,12 @@ __all__ = ["CLIENT_CREDS_ENV_VARS", "prompt_for_user_token"]
import logging import logging
import os import os
import warnings import warnings
from types import TracebackType
import spotipy import spotipy
import urllib3
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
CLIENT_CREDS_ENV_VARS = { CLIENT_CREDS_ENV_VARS = {
@ -142,3 +147,29 @@ def normalize_scope(scope):
return " ".join(sorted(scopes)) return " ".join(sorted(scopes))
else: else:
return None return None
class Retry(urllib3.Retry):
"""
Custom class for printing a warning when a rate/request limit is reached.
"""
def increment(
self,
method: str | None = None,
url: str | None = None,
response: urllib3.BaseHTTPResponse | None = None,
error: Exception | None = None,
_pool: urllib3.connectionpool.ConnectionPool | None = None,
_stacktrace: TracebackType | None = None,
) -> urllib3.Retry:
if response:
retry_header = response.headers.get("Retry-After")
if self.is_retry(method, response.status, bool(retry_header)):
logging.warning("Your application has reached a rate/request limit. "
f"Retry will occur after: {retry_header}")
return super().increment(method,
url,
response=response,
error=error,
_pool=_pool,
_stacktrace=_stacktrace)