A small Python library of decorators to help make your application more resilient. Currently, there are two decorators provided:
- Retryable – automatically re-calls the wrapped function if an exception is raised.
- CircuitBreaker – prevent calls to the wrapped function if it is known to currently be failing.
The documentation here will be brief, but hopefully you’ll be able to make sense of it by reading the docstrings.
Installation
Built for Python >=3.6
1. Retryable
You can use the @Retryable
decorator on any function to automatically retry calling it in case it throws an exception. One use-case would be if you make a remote call to an external API which returns the HTTP status code 500. Maybe it’s just a very temporary issue, in which case you might as well try a few more times.
# Use default configuration @Retryable def get_github(): res = requests.get('https://api.github.com') if res.status == '500': raise ThisFailedError() # Configure your own max retries, backoff time # between attempts, and more @Retryable(max_retries=5, backoff=1000) def get_github(): requests.get('https://api.github.com') if res.status == '500': raise ThisFailedError()
2. CircuitBreaker
If you make a remote call, and it keeps failing, you may want to stop making this call to save your API usage quota or lower the response time of something that would be failing anyway. In that case, a circuit breaker comes handy.
Currently, this decorator stops calling the decorated function after a configured number of failures in a row (the circuit breaker “opens”) and immediately returns the most recent exception instead. After a wait period, the circuit breaker allows new calls to the decorated function. You can also supply the optional argument sliding_window_length
– then the circuit breaker will keep a sliding window of the most recent results in a list. If the number of failures in the sliding window reach the max_attempts
threshold, the circuit breaker will open.
@CircuitBreaker def get_github(): res = requests.get('https://api.github.com') if res.status == '500':