Skip to main content

🌿 tranq

Calm error handling for Python – decorator-based, zero boilerplate.

GitHub PyPI Python 3.9+ License: MIT


🧘 Why tranq?

Writing repetitive try/except blocks clutters your code. tranq gives you declarative error handling with decorators, context managers, and smart retry strategies, so you can focus on business logic.

Feature Description
🧘 Tranquil Clean, readable, and maintainable.
🔁 Smart retries Exponential, linear, Fibonacci backoff, jitter, and max delay.
🚦 Circuit Breaker Prevent cascading failures (sync & async).
🧪 Conditional retry On specific exceptions or result values.
📦 Retry groups All-or-nothing execution for multiple functions.
📊 Built‑in metrics Monitor performance and error rates.
📝 Pluggable reporters Send errors to files (JSON), Sentry, Slack, or custom.
🧩 Context manager Use with tranq.retry(...): when decorators aren't ideal.
🔧 Stateful retry Persist attempt count across calls (thread/async safe).
🎭 Mock errors Test your error handling with ease.
💉 Dependency Injection Inject dependencies into decorated functions.
🌐 Global Policy Set defaults once, override per function.

📦 Installation

pip install tranq

Requires Python 3.9 or later.


⚡ Quick Start

Decorator (@handle)

import tranq

@tranq.handle(on=ValueError, retry=3, delay=0.5, backoff=2.0)
def risky():
    ...

Async (@handle_async)

@tranq.handle_async(on=ConnectionError, retry=2, fallback=lambda: "offline")
async def fetch_data():
    ...

Circuit Breaker

cb = tranq.CircuitBreaker(failure_threshold=5, timeout=60)

@tranq.handle(circuit_breaker=cb)
def call_unstable_service():
    ...

Context Manager

with tranq.retry(on=ValueError, retry=2) as ctx:
    result = ctx.run(my_function, arg1, arg2)

Retry Group (all-or-nothing)

group = tranq.retry_group(step1, step2, step3, on=Exception, retry=1)
results = group.run()

🔍 Features in Depth

1. Retry with Backoff

Choose from exponential, linear, or Fibonacci backoff. Add jitter to avoid thundering herds.

@tranq.handle(
    on=TimeoutError,
    retry=5,
    delay=0.1,
    backoff=2.0,
    backoff_strategy="exponential",  # "linear", "fibonacci", or custom callable
    max_delay=10.0,
    jitter=True,
)
def fetch():
    ...

2. Conditional Retry

  • retry_if – retry only when the exception matches a condition.
  • retry_on_result – retry if the result is unacceptable (e.g., None).
@tranq.handle(
    on=requests.RequestException,
    retry_if=lambda e: e.response.status_code == 429,  # rate-limit
    retry=3,
)
def call_api():
    ...

3. Global Policy

Set defaults for your entire application once.

tranq.set_global_policy(tranq.Policy(
    retry=3,
    delay=0.5,
    backoff=2.0,
    reraise=False,
))

# All @handle calls now inherit these defaults
@tranq.handle(on=ValueError)
def my_func():
    ...

4. Reporters (JSON file, Sentry, Slack)

from tranq import FileReporter, SentryReporter, SlackReporter

reporters = [
    FileReporter("/var/log/tranq_errors.json"),  # Writes JSON lines
    SentryReporter(dsn="..."),
    SlackReporter(webhook_url="..."),
]

@tranq.handle(on=Exception, reporters=reporters)
def critical_task():
    ...

5. Metrics & Profiling

@tranq.handle(metrics=True, metric_prefix="myapp")
def expensive_op():
    ...

from tranq import get_metrics, profile, get_profile

@profile
def heavy_computation():
    ...

print(get_metrics())
print(get_profile("heavy_computation"))

🚀 Advanced Example

Combining multiple features for a robust API call:

cb = tranq.CircuitBreaker(failure_threshold=3, timeout=60)

@tranq.handle(
    on=requests.RequestException,
    retry=5,
    backoff_strategy="fibonacci",
    max_delay=30,
    jitter=True,
    retry_if=lambda e: e.response.status_code in (429, 503),
    circuit_breaker=cb,
    metrics=True,
    metric_prefix="api",
    reporters=[tranq.FileReporter("api_errors.json")],
    fallback=lambda: {"status": "fallback"},
)
def fetch_from_external_api():
    ...

📚 API Reference

  • Decorators: handle(...), handle_async(...)
  • Context Manager: retry(...)
  • Retry Groups: retry_group(...), async_retry_group(...)
  • Circuit Breakers: CircuitBreaker(...), AsyncCircuitBreaker(...)
  • Policies: Policy, set_global_policy(), get_global_policy()
  • Reporters: Reporter, FileReporter, SentryReporter, SlackReporter
  • Utilities: get_metrics(), reset_metrics(), profile(), get_profile(), mock_errors()
  • Exceptions: TranqError, RetryExhaustedError, CircuitBreakerError, ResultNotAcceptedError, RetryGroupError

📖 Full documentation, 20 runnable examples, and 120+ tests are available on GitHub.


📄 License

MIT © RaptorVampire


Happy error handling! 🧘

Release files for tranq 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tranq 0.3.0
File Size Uploaded
tranq-0.3.0.tar.gz 20.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tranq 0.3.0
File Interpreter ABI Platform
tranq-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / tranq-0.3.0.tar.gz

Download URL tranq-0.3.0.tar.gz
Size 20.0 kB
Tags Source
SHA-256 checksum
How to use checksums
bc5eb7cb9527e00f7788005c0e4861a04d63cd4c2b991e408031354d3e1bcb37
BLAKE2b-256 checksum
How to use checksums
7f8efc390aa0b9b15f97accc5e07d5af3427f546417d81d3c704ca38c2aa78aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / tranq-0.3.0-py3-none-any.whl

Download URL tranq-0.3.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d6043c61ecb85293ceaf37750f8bdea11c9290eee346673411b6eb1e6ac17cb6
BLAKE2b-256 checksum
How to use checksums
2562ad5f6692d065991e6c4b163cfafdd98980df3f5082aec26283c7d6eddba5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release history Release notifications | RSS feed

1.1.0

2 release files

1.0.0

2 release files

This release

0.3.0 This release

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page