Skip to content

blackbull.config

blackbull.config

Declarative application configuration — :class:AppConfig.

AppConfig is a small, typed, immutable holder for the server-facing settings that :meth:blackbull.BlackBull.run (and :func:blackbull.serve) already accept as keyword arguments. It lets an application declare those settings once::

from blackbull import BlackBull, AppConfig

app = BlackBull(config=AppConfig(
    port=8443,
    certfile='cert.pem',
    keyfile='key.pem',
    workers=4,
))

if __name__ == '__main__':
    app.run()          # picks up the config; no flags to thread through

Resolution precedence in :meth:BlackBull.run is, highest to lowest (see :func:resolve_run_config):

  1. an explicit keyword argument to run(...)app.run(port=9000) always wins;
  2. a BLACKBULL_* environment variable, for the deploy-time settings (BLACKBULL_PORT / CERT / KEY / UNIX_PATH / RELOAD);
  3. the same BLACKBULL_* key in a .env file in the working directory (requires the [dotenv] extra; absent it, only the real environment is consulted);
  4. the value declared on the bound :class:AppConfig (if any);
  5. the built-in default baked into :func:blackbull.serve.

AppConfig deliberately mirrors only the parameters serve already exposes — it is not a general-purpose settings store. Per-request and server-tuning knobs (window sizes, timeouts, queue depths beyond the two listed here, workers, max_connections, …) continue to live in :mod:blackbull.env and are sourced from BB_* environment variables — BLACKBULL_* is the deployment namespace, BB_* the tuning one.

host is intentionally absent: BlackBull's socket layer binds dual-stack on all interfaces (see :meth:blackbull.server.ASGIServer.open_socket), so a per-interface host field would silently do nothing. Use unix_path or inherited_fd for non-TCP binds.

AppConfig dataclass

Immutable, declarative startup configuration for a BlackBull app.

Every field corresponds one-to-one with a keyword argument of :func:blackbull.serve / :meth:blackbull.BlackBull.run. Fields left at their sentinel default (None, or 0 for port, or False for reload) defer to serve's own built-in default unless an explicit run(...) argument overrides them.

log_config_sources(resolved, sources)

Log one INFO line per deploy setting that was configured non-trivially.

Only the BLACKBULL_*-resolvable deploy settings whose value came from an environment variable, .env, or an :class:AppConfig are reported — explicit call-site arguments (the author already knows them) and plain defaults are left silent to keep startup quiet. Paths are logged; secrets are not (a keyfile path is configuration, its contents never touch the log).

resolve_run_config(explicit, config)

Resolve every run() setting and record where each value came from.

Precedence, highest to lowest:

  1. an explicit run(...) keyword argument (anything not None);
  2. a BLACKBULL_* environment variable (for the deploy-time settings in :data:_ENV_VARS);
  3. a BLACKBULL_* entry in a .env file ([dotenv] extra);
  4. the bound :class:AppConfig field, if declared (non-default);
  5. the built-in default.

Returns (resolved, sources) where resolved maps each run() parameter to its final value and sources maps it to a short provenance label (argument / $BLACKBULL_PORT / .env / AppConfig / default) for startup logging.