resilient-result
Resilience mechanisms with Result types.
from resilient_result import resilient, Result
# Simple: perfect defaults for most cases
@resilient()
async def call_api(url: str) -> str:
return await http.get(url)
# Advanced: compose individual mechanisms
@timeout(seconds=10)
@retry(attempts=5)
async def robust_call(url: str) -> str:
return await http.get(url)
result: Result[str, Exception] = await call_api("https://api.example.com")
if result.success:
data = result.unwrap() # Extract data safely
print(data)
else:
print(f"Failed: {result.error}") # Inspect error directly
Why resilient-result? Network calls fail. Databases timeout. APIs rate limit. Handle it cleanly without exception soup.
Observability built-in: Enable logging.getLogger('resilient_result').setLevel(logging.DEBUG) to see retry attempts and recovery.
📖 Result API | 🔧 Resilience Patterns
Installation
pip install resilient-result
Core Features
Progressive Disclosure
from resilient_result import resilient, retry, timeout, circuit, rate_limit
# Simple: Just works with reasonable defaults
@resilient() # 2 attempts, 1s backoff, 30s timeout
async def simple_operation():
return await external_service()
# Advanced: Compose individual mechanisms
@rate_limit(rps=100) # Rate limiting (100 rps default)
@circuit(failures=3) # Circuit breaker (1 minute window)
@timeout(seconds=10) # Time-based protection
@retry(attempts=5) # Retry mechanism
async def critical_operation():
return await external_service()
Result Usage
from resilient_result import Result, Ok, Err
# Pattern 1: Check then unwrap
result = await call_api("https://api.example.com")
if result.success:
data = result.unwrap()
process(data)
# Pattern 2: Error inspection for conditional logic
result = await call_api("https://api.example.com")
if result.failure and "rate_limit" in result.error:
await asyncio.sleep(60) # Backoff on rate limit
retry()
elif result.failure:
log_error(result.error)
# Pattern 3: Direct unwrap (raises exception on failure)
try:
data = result.unwrap()
process(data)
except ApiError as e:
log_error(e)
Policy Configuration
from resilient_result import Retry, Backoff, Circuit, resilient
# Explicit policy configuration
@resilient(
retry=Retry(attempts=5, timeout=60),
backoff=Backoff.exp(delay=0.1, max_delay=10), # Jitter enabled by default
circuit=Circuit(failures=3, window=60) # 1 minute window
)
async def custom_operation():
return await external_service()
# Shorthand for common patterns
@resilient(retry=Retry(attempts=5)) # Just more attempts
@resilient(timeout=60) # Just longer timeout
async def database_operation():
return await db.query()
Parallel Operations
from resilient_result import Result
# Collect multiple async operations
operations = [fetch_user(1), fetch_user(2), fetch_user(3)]
result = await Result.collect(operations)
if result.success:
users = result.unwrap() # All succeeded
else:
try:
result.unwrap() # Raises first failure
except Exception as e:
print(f"First failure: {e}")
Error Inspection Patterns
# Canonical API: 3 ways to work with Results
result = await call_api("https://api.example.com")
# 1. Status checking
if result.success:
print("Success!")
if result.failure:
print("Failed!")
# 2. Error inspection (without exceptions)
if result.failure:
error_msg = result.error
if "network" in str(error_msg):
retry_with_backoff()
elif "auth" in str(error_msg):
refresh_token()
# 3. Value extraction (raises on failure)
try:
data = result.unwrap()
process(data)
except Exception as e:
handle_error(e)
License
MIT - Build amazing resilient systems! 🚀
🗺️ Roadmap
Release files for resilient-result 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| resilient_result-0.4.1.tar.gz | 10.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| resilient_result-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.5 kB
Release files / resilient_result-0.4.1.tar.gz
| Download URL | resilient_result-0.4.1.tar.gz |
|---|---|
| Size | 10.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6f7f3d8f1e513058790ba415ed519e82f81d1e4aa2ed4f32a16ee158ea3fa8c7
|
|
BLAKE2b-256 checksum How to use checksums |
68190dea2f5095d26aa6d4aa496d1945531893b7d8eaf9f2691ce410c0648376
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.10 Darwin/24.5.0
|
Release files / resilient_result-0.4.1-py3-none-any.whl
| Download URL | resilient_result-0.4.1-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
31edb802ea60a313c7fbf15a501bc2aec023794a2b64ffa5e7424684687603df
|
|
BLAKE2b-256 checksum How to use checksums |
dcb0abf94b578d042ba11936c2239746c8ee835007e86e35b78f225cf09d0612
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.10 Darwin/24.5.0
|