| |
| import time |
| import random |
| from functools import wraps |
| from google.api_core import exceptions |
| import gradio as gr |
|
|
| def retry_with_exponential_backoff( |
| func, |
| initial_delay: float = 2, |
| exponential_base: float = 2, |
| jitter: bool = True, |
| max_retries: int = 5, |
| ): |
| """ |
| A decorator to retry a function with exponential backoff for API calls. |
| It specifically catches google.api_core.exceptions.ResourceExhausted. |
| """ |
|
|
| @wraps(func) |
| def wrapper(*args, **kwargs): |
| num_retries = 0 |
| delay = initial_delay |
|
|
| while True: |
| try: |
| return func(*args, **kwargs) |
| except exceptions.ResourceExhausted as e: |
| num_retries += 1 |
| if num_retries > max_retries: |
| |
| raise gr.Error( |
| f"Maximum number of retries ({max_retries}) exceeded. The API is still busy. Please try again later." |
| ) from e |
|
|
| if jitter: |
| delay *= exponential_base * (1 + random.random()) |
| else: |
| delay *= exponential_base |
|
|
| |
| print(f"Rate limit exceeded. Retrying in {delay:.2f} seconds...") |
| time.sleep(delay) |
| except Exception as e: |
| |
| raise gr.Error(f"An unexpected error occurred: {e}") |
|
|
| return wrapper |
|
|