Spaces:
Running
Running
| """ | |
| RETRY UTILITY | |
| ============= | |
| Calls a function and, if it raises, retries a few times with exponential backoff. | |
| Used for Groq and Tavily API Calls so temporary rate limits or network blips | |
| don't immediately fail the request. | |
| Example: | |
| response = with_retry(lambda: groq_client.chat(...) max_retries=3, initial_delay=1.0) | |
| """ | |
| import logging | |
| import time | |
| from typing import TypeVar, Callable | |
| logger = logging.getLogger("J.A.R.V.I.S") | |
| T = TypeVar("T") | |
| def with_retry( | |
| fn: Callable[[], T], | |
| max_retries: int = 3, | |
| initial_delay: float = 1.0, ) -> T: | |
| last_exception = None | |
| delay = initial_delay | |
| for attempt in range(max_retries): | |
| try: | |
| return fn() | |
| except Exception as e: | |
| last_exception = e | |
| if attempt == max_retries - 1: | |
| raise | |
| logger.warning( | |
| "Attempt %s/%s failed (%s). Retrying in %.1fs: %s", | |
| attempt + 1, | |
| max_retries, | |
| fn.__name__ if hasattr(fn, "__name__") else "call", | |
| delay, | |
| e, | |
| ) | |
| time.sleep(delay) | |
| delay *= 2 | |
| raise last_exception | |