Skip to content

Configuration

DbkitConfig dataclass

DbkitConfig(
    databases: Mapping[str, DatabaseConfig],
    environment: str = "default",
    defaults: Defaults = Defaults(),
    connection_budget: ConnectionBudgetConfig = ConnectionBudgetConfig(),
    max_engines: int | None = None,
    max_databases: int | None = None,
    evict_lru_engines: bool = False,
)

Root configuration object (§30).

from_dict classmethod

from_dict(
    data: Mapping[str, Any],
    *,
    environ: Mapping[str, str] | None = None,
    expand: bool = True,
) -> DbkitConfig

Build and validate a config from a plain dict (e.g. parsed YAML/JSON).

${VAR}/${VAR:-default} placeholders in string values are expanded against environ (default os.environ) unless expand=False.

from_yaml classmethod

from_yaml(
    path: str, *, environ: Mapping[str, str] | None = None
) -> DbkitConfig

Build and validate a config from a YAML file (requires dbkit[yaml]).

A top-level dbkit: wrapper key is unwrapped automatically, so a dbkit config can be embedded inside a larger application config file.

validate

validate() -> None

Raise :class:DatabaseConfigurationError if any database or the process-wide connection budget is invalid.

max_connections_per_process

max_connections_per_process() -> int

Sum of every target's pool ceiling — the worst-case connections this process opens.

connection_budget_report

connection_budget_report(
    replicas: int = 1,
) -> dict[str, int]

Cluster-wide connection projection (§10.3): per_process * replicas.

enforce_connection_budget

enforce_connection_budget() -> None

Fail startup if a configured per-process budget is exceeded (§10.3).

budget_enforcement_warnings

budget_enforcement_warnings() -> list[str]

Non-fatal warnings (§10.3) about unenforced connection budgets.

Always empty when environment == "development" — a local/dev process silently exceeding a budget is not the scenario this guards against. Outside development, an unconfigured or unenforced budget means a config change (e.g. a new shard) can silently push a fleet's total connections past PostgreSQL's max_connections with nothing failing until the database itself starts rejecting connections under load.

tls_warnings

tls_warnings() -> list[str]

Non-fatal warnings (§29) about DSNs with no explicit TLS posture.

dbkit delegates TLS entirely to the driver/DSN and never enforces it — this only flags, outside development, a target whose URL doesn't even state its intent (no sslmode/ ssl query parameter), which is a cheap, common misconfiguration to catch early.

redacted

redacted() -> DbkitConfig

Return a copy with all target URLs password-redacted (§30).

DatabaseConfig dataclass

DatabaseConfig(
    primary: TargetConfig,
    replicas: tuple[TargetConfig, ...] = (),
    concurrency: ConcurrencyConfig = ConcurrencyConfig(),
    connection_budget: ConnectionBudgetConfig = ConnectionBudgetConfig(),
)

A logically named database: one primary and zero or more read replicas (§21).

from_dict classmethod

from_dict(
    data: Mapping[str, Any], *, name: str = "database"
) -> DatabaseConfig

Build one database config from a plain dict — the same shape as an entry under the top-level databases mapping. Used by dynamic registration (§22.4).

validate

validate() -> None

Raise :class:DatabaseConfigurationError if the primary or any replica is invalid.

all_targets

all_targets() -> tuple[TargetConfig, ...]

The primary followed by every replica, in configured order.

max_connections

max_connections(defaults: Defaults) -> int

This database's own connection ceiling: sum of primary + every replica's pool (§10.3).

enforce_connection_budget

enforce_connection_budget(
    defaults: Defaults, *, database_name: str
) -> None

Fail startup if this database alone exceeds its own configured budget (§10.3).

TargetConfig dataclass

TargetConfig(
    url: str,
    name: str = "primary",
    required: bool = True,
    weight: int = 1,
    pool: PoolConfig | None = None,
)

A single physical database endpoint (primary or one replica).

driver property

driver: str

Driver name parsed from the URL, e.g. psycopg or asyncpg.

dialect property

dialect: str

SQL dialect parsed from the URL, e.g. postgresql.

has_explicit_tls_setting property

has_explicit_tls_setting: bool

Whether the URL's query string sets an explicit sslmode/ssl parameter.

dbkit does not enforce TLS itself (that's the driver/infrastructure's job) — this only answers whether the DSN is explicit about its intent, for the dbkit check warning.

resolved_pool

resolved_pool(defaults: Defaults) -> PoolConfig

This target's own pool config, or defaults.pool if it doesn't override one.

validate

validate() -> None

Raise :class:DatabaseConfigurationError if the URL is missing or malformed.

PoolConfig dataclass

PoolConfig(
    size: int = 10,
    max_overflow: int = 5,
    timeout_seconds: float = 5.0,
    recycle_seconds: int = 1800,
    pre_ping: bool = True,
    use_lifo: bool = True,
    reset_on_return: str = "rollback",
    connect_timeout_seconds: float = 10.0,
    long_hold_warning_seconds: float = 2.0,
    disable_pooling: bool = False,
    pgbouncer_compatible: bool = False,
)

Connection pool settings, forwarded to SQLAlchemy's engine (§10.1-10.2).

max_connections property

max_connections: int

Ceiling of concurrent connections this pool can open.

validate

validate() -> None

Raise :class:DatabaseConfigurationError if any field is out of range.

RetryConfig dataclass

RetryConfig(
    attempts: int = 2,
    initial_delay_ms: float = 20.0,
    maximum_delay_ms: float = 250.0,
    multiplier: float = 2.0,
    jitter: str = "full",
    maximum_total_ms: float = 750.0,
    retry_reads: bool = True,
    retry_writes: bool = False,
)

Retry policy (§14). Writes are not retried unless explicitly enabled and idempotent.

retry_writes and Query.idempotent are both trust-based flags, not verified properties — enabling them means "I have checked this SQL is safe to run twice," not "dbkit made this SQL safe to run twice." See dbkit query-list for a best-effort static check that flags writes marked idempotent with no visible safety guard in their SQL text.

validate

validate() -> None

Raise :class:DatabaseConfigurationError if any field is out of range.

CircuitBreakerConfig dataclass

CircuitBreakerConfig(
    enabled: bool = False,
    failure_threshold: int = 10,
    window_seconds: float = 30.0,
    open_seconds: float = 10.0,
    half_open_max_calls: int = 2,
)

Per db+shard+role circuit breaker settings (§16).

validate

validate() -> None

Raise :class:DatabaseConfigurationError if any field is out of range.

BulkConfig dataclass

BulkConfig(
    default_batch_rows: int = 1000,
    max_batch_rows: int = 10000,
    max_payload_bytes: int | None = None,
)

Batch-sizing defaults for bulk operations (§19.1).

ConcurrencyConfig dataclass

ConcurrencyConfig(
    database: int | None = None,
    reads: int | None = None,
    writes: int | None = None,
    bulk_writes: int | None = None,
    expensive_queries: int | None = None,
)

Optional per-target concurrency limits, independent of pool size (§17).

ObservabilityConfig dataclass

ObservabilityConfig(
    metrics: bool = True,
    tracing: bool = False,
    log_parameters: bool = False,
    slow_query_ms: float = 500.0,
)

Logging/metrics/tracing toggles (§25).

ConnectionBudgetConfig dataclass

ConnectionBudgetConfig(
    maximum_per_process: int | None = None,
    enforce_at_startup: bool = False,
)

A cap on how many connections this process may open across all its engines (§10.3).

Defaults dataclass

Defaults(
    driver: str = "psycopg",
    query_timeout_seconds: float = 2.0,
    transaction_timeout_seconds: float = 5.0,
    long_transaction_warning_seconds: float = 5.0,
    pool: PoolConfig = PoolConfig(),
    retry: RetryConfig = RetryConfig(),
    circuit_breaker: CircuitBreakerConfig = CircuitBreakerConfig(),
    bulk: BulkConfig = BulkConfig(),
    observability: ObservabilityConfig = ObservabilityConfig(),
)

Process-wide defaults, overridable per-target/per-call.

validate

validate() -> None

Raise :class:DatabaseConfigurationError if any nested config is invalid.