A modern circuit breaker for Python — sync and async in a single class, sliding-window rate and slow-call detection, a type-safe API, and transparent integrations at the transport level.
Installationuv add interlock-cb # or: pip install interlock-cbinterlock-cb supports Python 3.11 and newer. The core uses only the standard library; external integrations are installed as optional extras.
QuickstartCreate one named breaker and reuse it around calls to the same dependency:
from interlock import CircuitBreaker, CircuitOpenError, Config breaker = CircuitBreaker( name='payments', config=Config(failure_rate_threshold=0.5, minimum_number_of_calls=20), ) @breaker def charge(amount: int) -> str: return gateway.charge(amount) try: receipt = charge(100) except CircuitOpenError as exc: print(exc)
The decorator preserves the function's signature and whether it is sync or
async. The same breaker also supports breaker.call(fn, ...), with breaker,
and async with breaker. See Getting started for all
calling styles and Configuration for every
threshold.
CircuitBreaker dispatches to separate sync
and async paths without duplicating the public API.py.typed and passes three strict type checkers.Start a new integration in METRICS_ONLY to observe real failure and slow-call
rates without rejecting traffic. The initial state is applied before a lazy
per-host breaker can admit its first request:
import httpx2 from interlock import Config, State from interlock.integrations.httpx2 import AsyncCircuitBreakerTransport transport = AsyncCircuitBreakerTransport( httpx2.AsyncHTTPTransport(), initial_state=State.METRICS_ONLY, config=Config(failure_rate_threshold=0.25, minimum_number_of_calls=50), listener=metrics_listener, )
Use an EventListener for production metrics. For local diagnostics,
transport.registry.get_existing(host) returns an already-created breaker
without creating one, so its state and snapshot() can be inspected safely.
After tuning thresholds, deploy a new transport with the default
initial_state=State.CLOSED; the enforcing instance starts with a fresh window.
See States and manual control.
Compose strategies in an explicit order (first is outermost) while keeping the breaker useful as a standalone primitive:
from interlock import CircuitBreaker, CircuitOpenError, Pipeline breaker = CircuitBreaker(name='recommendations') pipeline = ( Pipeline.builder() .fallback(lambda exc: [], on=(CircuitOpenError,)) .retry(attempts=4) # requires interlock-cb[tenacity] .circuit_breaker(breaker) .bulkhead(8) .timeout(2.0) .build() ) @pipeline async def fetch_picks(user: str) -> list[str]: return await client.get_picks(user)
Retries never hammer an open circuit, one hung attempt cannot eat the retry budget, and every decision is observable — see the pipeline guide.
IntegrationsThe httpx2 transport applies one breaker per host with no decorators at call
sites:
import httpx2 from interlock.integrations.httpx2 import CircuitBreakerTransport transport = CircuitBreakerTransport(httpx2.HTTPTransport()) client = httpx2.Client(transport=transport)
By default, transport exceptions and the canonical retryable statuses
(429, 500, 502, 503, 504) count as failures; 4xx client errors do not.
| Integration | Install | Documentation |
|---|---|---|
| httpx2 | interlock-cb[httpx2] |
Per-host transport |
| httpx | interlock-cb[httpx] |
Per-host transport |
| aiohttp | interlock-cb[aiohttp] |
Client middleware |
| requests | interlock-cb[requests] |
Session adapter |
| FastAPI | interlock-cb[fastapi] |
503 + Retry-After handler |
| Litestar | interlock-cb[litestar] |
503 + Retry-After handler |
| tenacity | interlock-cb[tenacity] |
Retry composition |
| Redis | interlock-cb[redis] |
Shared state |
| OpenTelemetry | interlock-cb[otel] |
Metrics listener |
The integrations overview also includes recipes for LLM SDKs and Flask/Django.
How it comparesinterlock-cb is young: its first release was in 2026. Established libraries such as pybreaker and circuitbreaker have carried production traffic for years and remain a better fit when maturity matters more than the feature differences.
| Feature | interlock-cb | pybreaker | circuitbreaker |
|---|---|---|---|
| Core states (closed / open / half-open) | ✅ | ✅ | ✅ |
| Native asyncio | ✅ | Tornado | ✅ |
| Trip condition | failure rate | consecutive failures | consecutive failures |
| Time-based sliding window | ✅ | — | — |
| Slow-call detection | ✅ | — | — |
| Shared state across processes | ✅ | ✅ | — |
| Composable resilience pipeline | ✅ | — | — |
Fully typed API (py.typed) |
✅ | — | — |
The full comparison covers more features as well as aiobreaker and purgatory. Something out of date or unfair? Please open a PR.
The reliability work compensating for the project's shorter production history includes 100% branch coverage, three strict type checkers, mutation testing of the state machine and engine, property- and model-based tests, and CI on free-threaded CPython. The correctness and testing page documents what is verified and where the limits are.
DocumentationThe full documentation is hosted at https://bagowix.github.io/interlock/. Start with:
For a deterministic, network-free demonstration of every state transition, run
the examples/ scripts or follow the walkthrough.
Bug reports and pull requests are welcome. See
CONTRIBUTING.md for the local setup and the checks a change
must pass, and CODE_OF_CONDUCT.md for community
expectations. Security issues: please follow SECURITY.md.
interlock is released under the MIT License.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Hybrid Phased Arrays for Mass Market Satellite User Terminals: Balancing Performance, Cost and Interference Resilience | 0 | 10 | 12-05-2026 |
| 2 | The Role of Precision Timing in Enabling Higher Bandwidth Per Rack Without Compromising Signal Integrity or Efficiency | 0 | 10 | 13-04-2026 |
| 3 | bocpy: Behavior-Oriented Concurrency in Python | 0 | 30 | 12-06-2026 |
| 4 | MO-Gymnasium - environments for reinforcement learning | 0 | 26.67 | 19-07-2026 |
| 5 | Robust LoRaWAN for distributed IoT | 0 | 10 | 30-03-2026 |
| 6 | Enabling Wideband Phased Arrays: SOI Tunable Filters and Heterogeneous Front-End Integration | 0 | 19.09 | 12-06-2026 |
| 7 | tsauditor: Statistical Auditor for Temporal Data Leakage | 0 | 10 | 03-08-2026 |
| 8 | AI-Driven Spatiotemporal Decoding of Counter-Propagating OAM States for Highly Resilient Physical-Layer Security | 0 | 5 | 14-07-2026 |
| 9 | Dissecting entanglement | 0 | 5 | 07-07-2026 |
| 10 | Memory-Delay Stability Switching and Ecological Thresholds in a Dimensionally Balanced Fractional-Order Predator-Prey Model | 0 | 5 | 15-07-2026 |