dynamic-config-py-web
Native web-framework integrations for dynamic-config-py: the wiring, the request scope, the health surface and the test doors — already written.
pip install "dynamic-config-py[fastapi]" # or [litestar] [flask] [quart]
pip install "dynamic-config-py[django]" # …[drf] and [ninja] for its API layers
pip install "dynamic-config-py[robyn]" # Experimental
pip install "dynamic-config-py[django-bolt]" # Experimental, Python 3.12+
from fastapi import Depends, FastAPI
from dynamic_config import DynamicConfig
from dynamic_config_web.fastapi import config_dependency, setup
config = DynamicConfig(Database, key="db").file("config.toml").env("APP_")
app = FastAPI()
setup(app, config)
database = config_dependency(config)
@app.get("/")
def index(db: Database = Depends(database)):
return {"host": db.host, "pool": db.pool_size}
That is the whole integration. setup loads before the first request,
watches while serving and stops on the way out; /healthz, /readyz and
/metrics are mounted; and every handler reads the configuration the
request began with.
What it does that a dependency function does not
One reading per request, enforced. The engine's own book states the
rule — read current() once per request and use that value for the whole
request — because a reload landing mid-request would otherwise show one
request two configurations. Here it is a contextvars scope opened by the
adapter: a second read is the same object, and a read outside a request
raises instead of quietly answering with whatever is installed at that
instant.
One watcher, however many times the app is built. A second watch()
on one configuration is AlreadyExists. uvicorn --reload rebuilds the
app on every edit and a test suite builds one per client, so the watcher
is leased and counted: the first holder starts it and the last one stops
it.
A watcher in every worker. A watcher is a thread, and a thread does
not survive fork() — but the engine's registration does, so a
gunicorn --preload worker would be refused a new one while nothing was
watching. Every lease re-arms itself in the child.
Liveness and readiness as different questions. /healthz never fails
on configuration: a process that cannot reload should stop receiving
traffic, not be restarted into reading the same broken file. /readyz
is where nothing installed, reloads failing and too stale answer 503.
Diagnostics only when you say so. /_config/explain and
/_config/check are not mounted at all without a guard — not
mounted-and-403, which would tell a scanner they exist.
The seven
| Framework | Extra | Seam | Tier |
|---|---|---|---|
| FastAPI | [fastapi] |
lifespan, Depends, APIRouter, ASGI middleware |
Beta |
| Litestar | [litestar] |
InitPlugin.on_app_init — lifespan, Provide, routes, middleware |
Beta |
| Flask | [flask] |
extension in app.extensions, Blueprint, before_request |
Beta |
| Quart | [quart] |
the async twin, on while_serving |
Beta |
| Django | [django] |
AppConfig.ready(), middleware, urls, a management command |
Beta |
| Django REST Framework | [drf] |
APIView + a permission class |
Beta |
| django-ninja | [ninja] |
a Router, and the operation auth= |
Beta |
| Robyn | [robyn] |
startup/shutdown events, @scoped handlers |
Experimental |
| django-bolt | [django-bolt] |
BoltAPI(lifespan=…, middleware=…), Router |
Experimental |
Each has a page or a section in
the book and a runnable example in
examples/;
all nine answer the same twelve conformance cases, and where one cannot —
Robyn's request scope — the suite says so by name rather than skipping
quietly.
What this package is not
It is not a second configuration API. Every value still comes from
dynamic-config-py, every diagnostic is the engine's, and the adapters
add no cache, no copy and no second source of truth — db.current() is
still the read path, and current() here is that read taken once per
request.
What you may build on and find unchanged tomorrow is written down: the Compatibility Contract.
License
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynamic_config_py_web-0.2.1.tar.gz.
File metadata
- Download URL: dynamic_config_py_web-0.2.1.tar.gz
- Upload date:
- Size: 152.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e82dad04db494cb0a40aecfe8b95ebe9078c2996ec6f9225a7d070e4df1f044
|
|
| MD5 |
2b09f9588025e14583bc564c72cac71b
|
|
| BLAKE2b-256 |
860a0dd5553447e1e967fd7690227c805698e1d7fb42a1022ddc908eb341c589
|
Provenance
The following attestation bundles were made for dynamic_config_py_web-0.2.1.tar.gz:
Publisher:
release.yml on dynamic-config-rs/dynamic-config-python-web
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynamic_config_py_web-0.2.1.tar.gz -
Subject digest:
8e82dad04db494cb0a40aecfe8b95ebe9078c2996ec6f9225a7d070e4df1f044 - Sigstore transparency entry: 2527159221
- Sigstore integration time:
-
Permalink:
dynamic-config-rs/dynamic-config-python-web@ab00372b162d42259869e998f309a37a16b77fc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dynamic-config-rs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab00372b162d42259869e998f309a37a16b77fc7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynamic_config_py_web-0.2.1-py3-none-any.whl.
File metadata
- Download URL: dynamic_config_py_web-0.2.1-py3-none-any.whl
- Upload date:
- Size: 73.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5991a31ea52179a4afba484658075f07faeda9cb503c2d9dfbecfa0cde8f05a2
|
|
| MD5 |
426b64a0d5a9a68966bb2b7e6f5a516e
|
|
| BLAKE2b-256 |
1aca2170f2e076d7fe9f73e25d7ab6a16b66beabf66578e12a62ea12a81e270d
|
Provenance
The following attestation bundles were made for dynamic_config_py_web-0.2.1-py3-none-any.whl:
Publisher:
release.yml on dynamic-config-rs/dynamic-config-python-web
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynamic_config_py_web-0.2.1-py3-none-any.whl -
Subject digest:
5991a31ea52179a4afba484658075f07faeda9cb503c2d9dfbecfa0cde8f05a2 - Sigstore transparency entry: 2527160252
- Sigstore integration time:
-
Permalink:
dynamic-config-rs/dynamic-config-python-web@ab00372b162d42259869e998f309a37a16b77fc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dynamic-config-rs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab00372b162d42259869e998f309a37a16b77fc7 -
Trigger Event:
push
-
Statement type: