baldur — Facade & Bootstrap
The top-level entry points: bootstrap wiring, the resilience facade, the leader-elected scheduler, SQL transaction scope, the admin server, and the framework-extra hooks. Every name below is covered by SemVer compatibility guarantees in v1.x.
Bootstrap
init
init(
quarantine_callback: (
Callable[[Exception], None] | None
) = None,
task_backend: str = "inline",
) -> None
Initialize the Baldur framework.
Idempotent — safe to call multiple times. Second and later calls are silent DEBUG-level no-ops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quarantine_callback
|
Callable[[Exception], None] | None
|
Optional callable invoked with the
|
None
|
task_backend
|
str
|
Scheduler execution mode (429 Part 6, C13).
- |
'inline'
|
Resilience facade
protect
protect(
name: str,
fn: Callable[[], T],
*,
fallback: Callable[[], T] | None = None,
dlq: bool | None = None,
retry: (
bool
| RetryPolicyConfig
| ResiliencePolicy[T]
| None
) = None,
circuit_breaker: bool | None = None,
timeout: float | None = _TIMEOUT_UNSET,
idempotency_key: (
str | Callable[[PolicyContext], str] | None
) = None,
idempotency_fail_open: bool | None = None,
idempotency_ttl: timedelta | None = None,
idempotency_execution_ttl: timedelta | None = None,
context: PolicyContext | None = None
) -> T
Run fn under Baldur's composed resilience pipeline and return its value.
Composition order (outer→inner): CircuitBreaker → Retry → Fallback. Final
failures optionally flow through DLQSink. fn runs at most
retry.max_attempts times; on all-failed without fallback the original
exception is re-raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Service identifier. Used as the Circuit Breaker key, Retry domain, and Prometheus label — keep it stable per downstream. |
required |
fn
|
Callable[[], T]
|
Zero-argument callable to protect. Must be idempotent when
|
required |
fallback
|
Callable[[], T] | None
|
Optional zero-argument callable invoked when |
None
|
dlq
|
bool | None
|
When True, final failures flow into the DLQ repository resolved
via |
None
|
retry
|
bool | RetryPolicyConfig | ResiliencePolicy[T] | None
|
|
None
|
circuit_breaker
|
bool | None
|
When True, wraps |
None
|
idempotency_key
|
str | Callable[[PolicyContext], str] | None
|
Opt into composed dedup so a retried (or re-submitted)
operation runs its side effect once, and a concurrent in-flight
duplicate (double-submit, duplicate webhook) is blocked rather than
executed in parallel. A |
None
|
idempotency_fail_open
|
bool | None
|
Cache-error fail direction for the dedup gate.
|
None
|
idempotency_ttl
|
timedelta | None
|
Dedup memory window — how long a completed operation
is remembered (how long duplicates stay blocked after success).
|
None
|
idempotency_execution_ttl
|
timedelta | None
|
In-flight execution window — how long a
running claim is honored before a crashed attempt becomes
retryable. |
None
|
context
|
PolicyContext | None
|
Optional |
None
|
Returns:
| Type | Description |
|---|---|
T
|
Whatever |
Raises:
| Type | Description |
|---|---|
Exception
|
Re-raises the underlying error when all branches fail and no fallback produced a value. |
IdempotencyDuplicateError
|
A duplicate was blocked by the dedup gate —
already completed (SKIP) or a concurrent in-flight call (ABORT). The
same type |
IdempotencyUnavailableError
|
A cache I/O error prevented the dedup check
and |
ValueError
|
|
aprotect
async
aprotect(
name: str,
fn: Callable[[], Awaitable[T]],
*,
fallback: Callable[[], Awaitable[T]] | None = None,
dlq: bool | None = None,
retry: (
bool
| RetryPolicyConfig
| ResiliencePolicy[T]
| None
) = None,
circuit_breaker: bool | None = None,
timeout: float | None = _TIMEOUT_UNSET,
idempotency_key: (
str | Callable[[PolicyContext], str] | None
) = None,
idempotency_fail_open: bool | None = None,
idempotency_ttl: timedelta | None = None,
idempotency_execution_ttl: timedelta | None = None,
context: PolicyContext | None = None
) -> T
Async counterpart of protect().
Current async limitations (PR1):
- circuit_breaker=True → raises NotImplementedError
(AsyncCircuitBreakerPolicy is pending).
- retry=True / retry=RetryPolicyConfig /
retry=<ResiliencePolicy> → raises NotImplementedError
(AsyncRetryPolicy and AsyncTenacityBridgePolicy are pending).
- None defaults resolve to "async-appropriate off" for CB/Retry,
regardless of ProtectSettings.default_* sync defaults.
Supported async kwargs: fallback, dlq, idempotency_key,
idempotency_fail_open, idempotency_ttl,
idempotency_execution_ttl, context. Idempotency dedup is meaningful here
even without async retry — it blocks a duplicate call (double-submit,
duplicate webhook): a concurrent in-flight duplicate or an already-completed
one raises IdempotencyDuplicateError instead of running the side effect.
idempotency_fail_open matches protect (cache-error fail direction;
fail-closed by default raises IdempotencyUnavailableError), as do
idempotency_ttl (dedup memory window) and idempotency_execution_ttl
(in-flight execution window). The
guard/hook are sync and invoked by AsyncPolicyComposer around the async
chain. When the async policies land, the raise paths will be removed without
any API change.
Dedup is exactly-once for the concurrent case; across a process crash
between the side effect and the post-execution mark the operation may run
again after the gate record's TTL expires (an essential at-least-once
limit — see protect).
protected
protected(
name: str,
*,
fallback: Callable[[], Any] | None = None,
dlq: bool | None = None,
retry: (
bool
| RetryPolicyConfig
| ResiliencePolicy[Any]
| None
) = None,
circuit_breaker: bool | None = None,
timeout: float | None = _TIMEOUT_UNSET,
idempotency_key: (
str | Callable[[PolicyContext], str] | None
) = None,
idempotency_fail_open: bool | None = None,
idempotency_ttl: timedelta | None = None,
idempotency_execution_ttl: timedelta | None = None,
context_from: (
Callable[..., PolicyContext] | None | Literal[False]
) = None
) -> Callable[[Callable[..., T]], Callable[..., T]]
Decorator form of protect().
Auto-detects coroutine functions and dispatches to aprotect() when
appropriate, so @protected(...) works uniformly for sync and async
callables. Arguments passed to the decorated function are forwarded to
fn via partial binding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Service identifier — see |
required |
fallback
|
Callable[[], Any] | None
|
Same as |
None
|
dlq
|
bool | None
|
Same as |
None
|
retry
|
bool | RetryPolicyConfig | ResiliencePolicy[Any] | None
|
Same as |
None
|
circuit_breaker
|
bool | None
|
Same as |
None
|
timeout
|
float | None
|
Same as |
_TIMEOUT_UNSET
|
idempotency_key
|
str | Callable[[PolicyContext], str] | None
|
Same as |
None
|
idempotency_fail_open
|
bool | None
|
Same as |
None
|
idempotency_ttl
|
timedelta | None
|
Same as |
None
|
idempotency_execution_ttl
|
timedelta | None
|
Same as |
None
|
context_from
|
Callable[..., PolicyContext] | None | Literal[False]
|
Controls auto-population of |
None
|
aprotected
aprotected(
name: str,
*,
fallback: Callable[[], Awaitable[Any]] | None = None,
dlq: bool | None = None,
retry: (
bool
| RetryPolicyConfig
| ResiliencePolicy[Any]
| None
) = None,
circuit_breaker: bool | None = None,
timeout: float | None = _TIMEOUT_UNSET,
idempotency_key: (
str | Callable[[PolicyContext], str] | None
) = None,
idempotency_fail_open: bool | None = None,
idempotency_ttl: timedelta | None = None,
idempotency_execution_ttl: timedelta | None = None,
context_from: (
Callable[..., PolicyContext] | None | Literal[False]
) = None
) -> Callable[
[Callable[..., Awaitable[T]]],
Callable[..., Awaitable[T]],
]
Async-only decorator. Use @protected for mixed sync/async callsites;
prefer @aprotected when you want a type-checker error on misuse
against a sync function.
context_from, idempotency_key, idempotency_fail_open,
idempotency_ttl, and idempotency_execution_ttl behave
identically to @protected (async parity). When AsyncCircuitBreakerPolicy /
AsyncRetryPolicy land, DLQ entries from async pipelines will already
carry the captured context.
Scheduler
get_leader_scheduler
get_leader_scheduler(
resource_name: str = DEFAULT_SCHEDULER_RESOURCE,
) -> LeaderScheduler
Return the LeaderScheduler singleton.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource_name
|
str
|
Resource name |
DEFAULT_SCHEDULER_RESOURCE
|
Returns:
| Type | Description |
|---|---|
LeaderScheduler
|
The LeaderScheduler instance |
SQL storage
sql_transaction
sql_transaction(conn: Any) -> Any
Suspend repo-scoped auto-commit for the duration of the block.
Usage::
with sql_transaction(conn):
dlq_repo.save(...)
cb_repo.update(...)
# single commit (or rollback on exception) applies to both.
All repositories whose get_connection returns conn during
the block skip their per-call commit. The context manager itself
issues the final commit, or rollback on exception.
Admin server
start_admin_server
start_admin_server(
port: int | None = None,
bind: str | None = None,
*,
register_shutdown: bool = True
) -> AdminServer
Public entry point — start the admin server.
Arguments override the corresponding settings when provided; otherwise
settings (BALDUR_ADMIN_*) apply. Subsequent calls return the already
running server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
port
|
int | None
|
Override |
None
|
bind
|
str | None
|
Override |
None
|
register_shutdown
|
bool
|
When True (default), integrates with
:class: |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
The |
AdminServer
|
class: |
Raises:
| Type | Description |
|---|---|
AdminAuthRequiredError
|
non-localhost bind without an API key. |
stop_admin_server
stop_admin_server(timeout: float = 5.0) -> None
Stop the singleton admin server if running. Idempotent.
Framework extras
fastapi_lifespan
async
fastapi_lifespan(
app: FastAPI,
) -> AsyncIterator[dict[str, Any]]
Initialize Baldur on app startup, drain on shutdown.
Yields an empty mapping so callers can attach lifespan-scoped state via
the standard lifespan_state pattern; the dict is reserved for
Baldur-internal use and may carry diagnostic state in future versions.
init_flask
init_flask(
app: Flask,
service_name: str | None = None,
rate_limit: int | None = None,
window_seconds: int | None = None,
) -> None
Initialize Baldur for a Flask app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Flask
|
The Flask application instance. |
required |
service_name
|
str | None
|
Optional upstream identity. When supplied,
CB pre-flight + post-response observation are enabled. When
|
None
|
rate_limit
|
int | None
|
Per-instance override for the middleware rate limit
(requests per window). |
None
|
window_seconds
|
int | None
|
Per-instance window size override. |
None
|