From bd34f12a4e3728ce53d3cc0947672f9456ac08f9 Mon Sep 17 00:00:00 2001 From: barry Date: Sat, 11 Apr 2026 12:40:05 +0200 Subject: [PATCH] format --- spotiplayer_pi/api.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/spotiplayer_pi/api.py b/spotiplayer_pi/api.py index 59b8e27..476ae56 100644 --- a/spotiplayer_pi/api.py +++ b/spotiplayer_pi/api.py @@ -1,5 +1,43 @@ import warnings import httpx +import functools +import asyncio + + +def retry_request(n_retries=3, timeout=5.0, backoff=1.5): + def decorator(func): + @functools.wraps(func) + async def wrapper(*args, **kwargs): + last_exc = None + + for attempt in range(n_retries): + try: + # inject timeout if function supports it + if "timeout" not in kwargs: + kwargs["timeout"] = timeout + + return await func(*args, **kwargs) + + except httpx.TimeoutException as e: + last_exc = e + warnings.warn(f"Timeout (attempt {attempt + 1}/{n_retries})") + + except httpx.RequestError as e: + last_exc = e + warnings.warn( + f"Request error (attempt {attempt + 1}/{n_retries}): {e}" + ) + + # backoff before retrying + if attempt < n_retries - 1: + await asyncio.sleep(backoff * (attempt + 1)) + + warnings.warn(f"All retries failed: {last_exc}") + return None + + return wrapper + + return decorator class Api: @@ -10,6 +48,7 @@ class Api: self.header = None self._client = httpx.AsyncClient(timeout=httpx.Timeout(5.0, connect=5.0)) + @retry_request(n_retries=10, timeout=5.0) async def refreshAuth(self) -> None: uri = "https://accounts.spotify.com/api/token" data = { @@ -26,6 +65,7 @@ class Api: self.header = {"Authorization": f"Bearer {self.access_token}"} return req["expires_in"] + @retry_request(n_retries=4, timeout=3.0) async def getPlaying(self): url = "https://api.spotify.com/v1/me/player/currently-playing" req = await self._client.get(url, headers=self.header)