mirror of https://github.com/kortix-ai/suna.git
59 lines
1.4 KiB
Python
59 lines
1.4 KiB
Python
import asyncio
|
|
from typing import TypeVar, Callable, Awaitable, Optional
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
async def retry(
|
|
fn: Callable[[], Awaitable[T]],
|
|
max_attempts: int = 3,
|
|
delay_seconds: int = 1,
|
|
) -> T:
|
|
"""
|
|
Retry an async function with exponential backoff.
|
|
|
|
Args:
|
|
fn: The async function to retry
|
|
max_attempts: Maximum number of attempts
|
|
delay_seconds: Delay between attempts in seconds
|
|
|
|
Returns:
|
|
The result of the function call
|
|
|
|
Raises:
|
|
The last exception if all attempts fail
|
|
|
|
Example:
|
|
```python
|
|
async def fetch_data():
|
|
# Some operation that might fail
|
|
return await api_call()
|
|
|
|
try:
|
|
result = await retry(fetch_data, max_attempts=3, delay_seconds=2)
|
|
print(f"Success: {result}")
|
|
except Exception as e:
|
|
print(f"Failed after all retries: {e}")
|
|
```
|
|
"""
|
|
if max_attempts <= 0:
|
|
raise ValueError("max_attempts must be greater than zero")
|
|
|
|
last_error: Optional[Exception] = None
|
|
|
|
for attempt in range(1, max_attempts + 1):
|
|
try:
|
|
return await fn()
|
|
except Exception as error:
|
|
last_error = error
|
|
|
|
if attempt == max_attempts:
|
|
break
|
|
|
|
await asyncio.sleep(delay_seconds)
|
|
|
|
if last_error:
|
|
raise last_error
|
|
|
|
raise RuntimeError("Unexpected: last_error is None")
|