eth-retry

raw JSON →
0.3.7 verified Fri May 01 auth: no python

eth-retry provides a decorator that automatically catches known transient exceptions common in the Ethereum/EVM ecosystem (RPC errors, rate limits, timeouts) and retries the decorated function. Current version is 0.3.7, with an active release cadence. Requires Python >=3.10.

pip install eth-retry
error ModuleNotFoundError: No module named 'eth-retry'
cause Using pip install eth-retry with hyphen in the package name, Python import uses underscores.
fix
Install with pip install eth-retry, but import as from eth_retry import eth_retry.
error TypeError: 'AsyncDecorator' object is not callable
cause Using eth_retry_async incorrectly on a non-async function or failing to await the decorated function.
fix
Ensure the decorated function is async and called with await: result = await my_async_func().
error AttributeError: 'function' object has no attribute 'retry'
cause Trying to access a .retry attribute on the decorated function, which does not exist.
fix
Do not attempt to access .retry. The decorator does not add such attribute.
gotcha The decorator only retries on specific known transient exceptions (e.g., RPC errors, rate limits, timeouts). Custom exceptions are not retried unless you use the `exceptions` parameter.
fix If you need to retry on other exceptions, pass them via exceptions=[...] in the decorator.
gotcha When using environment variables (e.g., ETH_RETRY_MAX_RETRIES), they are read at import time. Changes to environment variables after import will not affect behavior unless explicitly overridden in decorator kwargs.
fix Set environment variables before importing eth_retry, or use decorator kwargs to override.
breaking Python 3.8 and 3.9 are no longer supported as of v0.3.6. v0.3.5 was the last version with Python 3.8/3.9 support.
fix Upgrade to Python 3.10+ or pin eth-retry to <=0.3.5.

Basic usage of eth-retry for synchronous and asynchronous functions.

import os
from eth_retry import eth_retry, eth_retry_async

# Synchronous usage
@eth_retry
def fetch_balance(address: str) -> int:
    # Simulate RPC call that might fail
    return 100

result = fetch_balance('0x...')
print(result)

# Async usage
@eth_retry_async
async def fetch_balance_async(address: str) -> int:
    return 100

import asyncio
asyncio.run(fetch_balance_async('0x...'))