Retry, Cache, Circuit Breaker decorator for Python (sync + async)
Project description
🛡️ Repdeco
Repdeco (Resilience & Protection Decorator) is a powerful, all-in-one Python decorator designed to make your functions bulletproof. Whether you are dealing with flaky APIs, unstable database connections, or heavy computations, repdeco has you covered.
It provides a unified, elegant interface for Retries, Exponential Backoff, Timeouts, Circuit Breaking, and Memory Caching — seamlessly supporting both sync and async functions.
🚀 Features
- 🔄 Retries & Backoff — Automatically retry failing operations with optional exponential backoff.
- ⏱️ Timeouts — Stop execution if a function takes too long (safely works for both
asyncandsyncfunctions using ThreadPool). - 🔌 Circuit Breaker — Prevent cascading failures by failing fast when a downstream system is down.
- 💾 Caching — In-memory caching with Time-To-Live (TTL) to speed up repeated calls.
- ⚡ Sync & Async Ready — Use the exact same
@repdecodecorator for standarddefandasync def. - 📝 Metadata Preserved — Keeps your original function names and docstrings intact (
@functools.wrapssupport).
📦 Installation
pip install repdeco
💡 Quick Start & Usage
Import the decorator into your project:
import time
import asyncio
from repdeco.core import repdeco
1. Retries with Exponential Backoff
If the function raises an exception, it will retry up to retry times. The backoff=1 means it will wait 1s, 2s, and 4s between attempts.
@repdeco(retry=3, backoff=1)
def fetch_data():
print("Fetching data...")
raise ConnectionError("Network unstable")
# Will try 4 times total (1 initial + 3 retries) before raising the error.
2. Timeouts (Sync & Async)
Enforce a strict time limit. If the function exceeds timeout seconds, it will raise a TimeoutError.
@repdeco(timeout=2)
def slow_sync_task():
time.sleep(5)
return "Done"
@repdeco(timeout=2)
async def slow_async_task():
await asyncio.sleep(5)
return "Done"
3. Circuit Breaker
If a function fails cb_threshold times in a row, the circuit opens. It immediately blocks further calls for cb_timeout seconds, raising an Exception instantly without even trying to run the failing function.
@repdeco(cb_threshold=5, cb_timeout=60)
def fragile_api_call():
# If this fails 5 times, it gets blocked for 60 seconds
pass
Circuit states:
CLOSED (normal) → [N failures] → OPEN (blocked) → [timeout expires] → HALF-OPEN → [success] → CLOSED
4. Caching with TTL (Time-To-Live)
Cache the results of expensive function calls based on their arguments.
@repdeco(cache_ttl=300) # Cache for 5 minutes
def heavy_computation(x, y):
print("Calculating...")
time.sleep(3)
return x * y
print(heavy_computation(5, 5)) # Takes 3 seconds → returns 25
print(heavy_computation(5, 5)) # Instant! (Returns cached 25)
5. The "All-in-One" Combo
You can combine all features to create highly resilient functions. The decorator evaluates logic in this order:
Cache → Circuit Breaker → Timeout → Retries
@repdeco(
retry=2,
backoff=2,
timeout=5,
cache_ttl=60,
cb_threshold=3,
cb_timeout=30
)
async def resilient_web_scraper(url):
# Your robust scraping logic here
pass
⚙️ Configuration Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
retry |
int |
0 |
Number of times to retry the function after an initial failure. |
retry_on |
tuple |
None |
Specific exception classes to catch and retry on (e.g., (ConnectionError,)). If None, retries on all exceptions. |
backoff |
int/float |
0 |
Base multiplier for exponential backoff sleep time (backoff * 2^attempt). 0 means retry immediately. |
timeout |
int/float |
None |
Maximum seconds the function is allowed to run before raising a TimeoutError. |
cache_ttl |
int/float |
0 |
Time-To-Live in seconds for the in-memory cache. 0 disables caching. |
cb_threshold |
int |
5 |
Number of consecutive failures before the Circuit Breaker opens. |
cb_timeout |
int/float |
10 |
Seconds the Circuit Breaker remains open before attempting a half-open retry. |
📜 License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repdeco-0.1.2.tar.gz.
File metadata
- Download URL: repdeco-0.1.2.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5bd189fdb8cb442500837936ad74b78e78a6427f05fe68e2cbb7748edcb5e12
|
|
| MD5 |
61b21145f70981e76bde7afb013c80b3
|
|
| BLAKE2b-256 |
30c1f798e89c03dcbe4778e0e623139e8f441059bbd95f20f72dfe6bdcf8afbf
|
Provenance
The following attestation bundles were made for repdeco-0.1.2.tar.gz:
Publisher:
publish.yml on bell77m/repdeco
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repdeco-0.1.2.tar.gz -
Subject digest:
d5bd189fdb8cb442500837936ad74b78e78a6427f05fe68e2cbb7748edcb5e12 - Sigstore transparency entry: 1185982221
- Sigstore integration time:
-
Permalink:
bell77m/repdeco@654ad792f409093c1c5fd1e6fd1a57538556a407 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/bell77m
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@654ad792f409093c1c5fd1e6fd1a57538556a407 -
Trigger Event:
push
-
Statement type:
File details
Details for the file repdeco-0.1.2-py3-none-any.whl.
File metadata
- Download URL: repdeco-0.1.2-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb0e322bd10d53ee7c803fbb1b1126d2b666764735b56d0c9b5b92ef58df0a9d
|
|
| MD5 |
6ed606063a28cf4edcee5326c65ba2c4
|
|
| BLAKE2b-256 |
3a339d4a3a4e94efa582bc82cd08966994f275b39dc851bf116db18de1871081
|
Provenance
The following attestation bundles were made for repdeco-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on bell77m/repdeco
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repdeco-0.1.2-py3-none-any.whl -
Subject digest:
eb0e322bd10d53ee7c803fbb1b1126d2b666764735b56d0c9b5b92ef58df0a9d - Sigstore transparency entry: 1185982237
- Sigstore integration time:
-
Permalink:
bell77m/repdeco@654ad792f409093c1c5fd1e6fd1a57538556a407 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/bell77m
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@654ad792f409093c1c5fd1e6fd1a57538556a407 -
Trigger Event:
push
-
Statement type: