feat: exponential backoff

This commit is contained in:
2026-05-14 12:23:18 +02:00
parent b0a7202f32
commit e42cddd645

32
api.py
View File

@@ -30,6 +30,9 @@ from authomatic.adapters import WerkzeugAdapter
from authomatic.providers import oauth2
from authomatic.providers import PROVIDER_ID_MAP as AUTHOMATIC_PROVIDER_ID_MAP
import random
import time
import requests
@@ -294,11 +297,32 @@ def get_valid_access_token(spotify_user_id: str) -> str:
# ----------------------------
def spotify_get(url: str, access_token: str, params: dict | None = None) -> dict:
"""GET a Spotify Web API endpoint and return the parsed JSON body."""
"""
GET a Spotify Web API endpoint and return the parsed JSON body.
Retries on HTTP 429 and 503 with exponential backoff and optional Retry-After,
so brief Spotify rate limits often clear before we surface an error to the app.
"""
headers = {"Authorization": f"Bearer {access_token}"}
r = requests.get(url, headers=headers, params=params)
r.raise_for_status()
return r.json()
backoff_sec = 1.0
max_attempts = 8
params_eff = params
for attempt in range(max_attempts):
r = requests.get(url, headers=headers, params=params_eff)
if r.status_code in (429, 503) and attempt < max_attempts - 1:
wait = backoff_sec
ra = r.headers.get("Retry-After")
if ra:
try:
wait = max(wait, float(ra))
except ValueError:
pass
wait = min(wait, 120.0)
time.sleep(wait + random.random() * 0.25 * wait)
backoff_sec = min(backoff_sec * 2.0, 60.0)
continue
r.raise_for_status()
return r.json()
def spotify_get_paginated(