Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Konfig

Quality Gate Status Reliability Rating Security Rating Maintainability Rating Vulnerabilities Bugs Lines of Code Duplicated Lines (%)

Settings management, pluggable secrets, and run-scoped logging for Python applications.

Konfig provides three foundational capabilities every Python application needs, with an optional lightweight app lifecycle context manager that ties them together. It is a clean-sheet replacement for dtPyAppFramework.

Features

  • Layered settings with system/user/env/runtime precedence and persistent writes
  • Pluggable secrets with OS keyring, AES-encrypted file, and AWS Secrets Manager backends
  • Run-scoped logging with historical retention, structured JSON mode, and stdio-safe output
  • Optional centralised log forwarding: one nominated collector gathers every container's logs over pinned TLS, discovered automatically through the shared secrets store
  • Platform-aware defaults for config, data, and log directories (macOS, Linux, Windows)
  • Optional app lifecycle via a sync/async context manager — no inheritance required
  • Python 3.10+

Installation

pip install konfig

For AWS Secrets Manager support:

pip install konfig[aws]

Secrets

AWS Secrets Manager (designated secret)

Point konfig at a single AWS secret that holds a JSON bundle of your secrets (the secret must already exist):

export KONFIG_AWS_SECRETS_MANAGER=arn:aws:secretsmanager:eu-west-1:123456789012:secret:myapp/secrets-AbCdEf
from konfig import Secrets

secrets = Secrets()               # env var selects the AWS bundle backend
api_key = secrets.get("api_key")
secrets.set("api_key", "sk-new")  # read-modify-write back to the bundle

Requires pip install konfig[aws].

AWS Secrets Manager settings document (KONFIG_AWS_SETTINGS)

Deliver an application's entire configuration as one JSON document held in a single Secrets Manager secret — no config file or per-setting environment variables needed in the task definition:

export KONFIG_AWS_SETTINGS=arn:aws:secretsmanager:eu-west-1:123456789012:secret:myapp/settings-AbCdEf

The secret's SecretString must be a JSON object holding the same nested settings tree a config file would. A plain secret name is also accepted; the region then comes from the default AWS provider chain (with an ARN it is taken from the ARN). An equivalent constructor argument exists for programmatic use — Settings(aws_settings=...) — with the environment variable winning when both are set. Requires pip install konfig[aws].

Precedence (highest to lowest): runtime -> env vars -> AWS settings -> user file -> system file -> defaults — environment variables remain the operator's immediate per-container override, while the AWS document overrides anything baked into the image.

Behaviour:

  • Read-only. settings.set(...) keeps writing to the runtime layer or config files exactly as before.
  • Fail fast. A missing/unreadable secret, non-JSON payload, or non-object top level raises at startup rather than silently degrading to defaults. Error messages name the secret, never its payload.
  • Fetched once. The document is read at construction and only re-fetched by settings.reload(); there is no background polling.
  • Composes with secrets. Values in the document may be secret:// URIs, resolved as usual by the active secrets backend.

This is independent of KONFIG_AWS_SECRETS_MANAGER. Pointing both at the same secret works, but keeping configuration and secret material in separate Secrets Manager entries is recommended so IAM can distinguish "may read config" from "may read credentials".

First boot on AWS: seeded stores

When konfig starts against empty stores (an empty or whitespace-only SecretString, or a bare {}), it writes a template for the operator instead of leaving them to transcribe documentation:

  • The KONFIG_AWS_SETTINGS settings secret is seeded with the application's defaults tree as pretty-printed JSON. Startup continues with reads resolving exactly as if the layer were absent.
  • The KONFIG_AWS_SECRETS_MANAGER bundle secret is seeded with a "CHANGEME" placeholder for every secret://<name> reference in the effective settings. Resolving an unpopulated placeholder logs a warning naming the key. AppContext runs this automatically at startup; when composing Settings and Secrets yourself, call secrets.seed_from(settings).

The intended first-boot flow: create the two (empty) secrets, grant secretsmanager:PutSecretValue on them for first boot, start once, edit the seeded documents, restart — and optionally drop the write grant again.

Seeding never touches a non-empty store (malformed payloads keep failing fast, and partial documents are never merged into), never creates secrets, and a failed seed write (for example AccessDenied under a read-only role) only logs a warning. Concurrent replicas racing the first boot are benign: every writer writes identical content. Operators who want no write attempt at all can disable seeding outright with KONFIG_AWS_SEED=false.

Running the LocalStack integration tests

The AWS integrations have opt-in integration tests that run against a local LocalStack container (no AWS account needed). They auto-skip when LocalStack is not running, so they never affect the normal test run.

docker compose up -d         # start LocalStack
pip install -e ".[dev,aws]"  # boto3 + dev tools
pytest -m localstack         # run only the integration test
docker compose down          # stop LocalStack

The tests look for LocalStack at http://127.0.0.1:4566, the port docker-compose.yml publishes. If it is published somewhere else, point the tests at it with KONFIG_TEST_LOCALSTACK_URL (an http(s) URL with a host and a port):

KONFIG_TEST_LOCALSTACK_URL=http://127.0.0.1:24566 pytest -m localstack

Quick Start

from konfig import AppContext

with AppContext(
    name="My Application",
    version="1.0.0",
    config_file="config.yaml",
    env_prefix="MYAPP",
) as ctx:
    host = ctx.settings.get("database.host", "localhost")
    api_key = ctx.secrets.get("api_key")
    ctx.logger.info("Starting with host=%s", host)

For async applications:

async with AppContext(name="My Server", version="2.0.0") as ctx:
    await run_server(ctx.settings)

Config file format

The config file format is chosen by the KONFIG_CONFIG_FORMAT environment variable (yaml, json, or sqlite). When unset, the format is detected from the file extension, defaulting to YAML. Reading, updating, and creating settings work in every format. (TOML config files are still supported by extension detection, but are read-only and cannot be selected via KONFIG_CONFIG_FORMAT.)

export KONFIG_CONFIG_FORMAT=sqlite   # store settings in a SQLite database file
from konfig import Settings

settings = Settings(config_file="config.db")
settings.set("database.host", "localhost", persist="user")  # written to SQLite
settings.set("debug", True)                                  # omit persist: in-memory only
host = settings.get("database.host")

Centralised log forwarding

To collect every container's logs in one place, nominate one instance as the collector and turn on forwarding everywhere else. Each instance keeps its own local logs as before:

# On the collector (needs a persistent volume at its log directory)
KONFIG_LOG_COLLECTOR=true
KONFIG_LOG_COLLECTOR_ADVERTISE=log-collector:9020

# On every other instance
KONFIG_LOG_CENTRAL=true
KONFIG_LOG_INSTANCE_LABEL=worker-3   # optional

AppContext does the rest. The collector generates a TLS certificate and an access token and publishes them in the shared secrets store, senders discover them, and every record lands, tagged with its instance, in <log_dir>/central/latest/central.log on the collector. See Centralised Log Forwarding.

Each subsystem (Settings, Secrets, LogManager) can also be used independently. See the full documentation in the docs/ directory:

Samples

Working examples are provided in the samples/ directory:

File Description
basic_settings.py Config files, defaults, env vars, overrides
secrets_usage.py Store, retrieve, and delete secrets
logging_demo.py Run-scoped logging with retention
app_context.py Full lifecycle with all subsystems
async_app.py Async context manager usage
custom_backend.py Implementing a custom SecretBackend
central_logging.py Centralised log forwarding: collector and sender roles

Development

CI installs the development tools from a hash-locked requirements file and then konfig itself. Do the same locally to get exactly the versions CI tests with (the lock covers Linux, macOS and Windows on Python 3.10 to 3.13, and includes the dev and aws extras):

python -m pip install --require-hashes --only-binary :all: -r requirements/dev.txt
python -m pip install --no-deps --no-build-isolation -e .

pip install -e ".[dev,aws]" still works when you do not need the locked versions.

The lock files are generated from the .in files beside them, together with pyproject.toml, by uv 0.13.6 (the version CI uses). Regenerate them from the repository root after changing a dependency in pyproject.toml or a .in file:

uv pip compile --universal --generate-hashes --python-version 3.10 requirements/build.in -o requirements/build.txt
uv pip compile --universal --generate-hashes --python-version 3.10 pyproject.toml requirements/dev.in --extra dev --extra aws -o requirements/dev.txt

uv keeps the versions already in the lock files; add --upgrade (or --upgrade-package <name>) to move them on. CI regenerates both files and fails if the result differs from what is committed.

The GitHub Actions in .github/workflows/ are pinned to full commit SHAs with the tag as a trailing comment; Dependabot (.github/dependabot.yml) proposes updates to them weekly, as one grouped pull request, and never touches the lock files.

pytest
pytest --cov=konfig
mypy src/konfig
black src/ tests/
isort src/ tests/

License

MIT License. See LICENSE for details.

Metadata

Release files for cognisn-konfig 0.5.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cognisn-konfig 0.5.0rc1
File Size Uploaded Provenance Actions
cognisn_konfig-0.5.0rc1.tar.gz 185.3 kB With provenance Details for cognisn_konfig-0.5.0rc1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cognisn-konfig 0.5.0rc1
File Interpreter ABI Platform Actions
cognisn_konfig-0.5.0rc1-py3-none-any.whl Python 3 none any Details for cognisn_konfig-0.5.0rc1-py3-none-any.whl

Total release size: 257.2 kB

Release files / cognisn_konfig-0.5.0rc1.tar.gz

Download URL cognisn_konfig-0.5.0rc1.tar.gz
Size 185.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c6d4b05e6d9fc53c39a75e3c6d46a56ab0f3816c4dfe0dd693caefcc2d0ac2f6
BLAKE2b-256 checksum
How to use checksums
edc6220ef26c1886c284eb18a474c0ee6028fe1fd015383fb0555d38b083a09d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / cognisn_konfig-0.5.0rc1-py3-none-any.whl

Download URL cognisn_konfig-0.5.0rc1-py3-none-any.whl
Size 71.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e88c60493782f0d8ac3ceeed5d37b8d1fcc3025f8ea3e5006c09e02cbec6cfd8
BLAKE2b-256 checksum
How to use checksums
90d4e140e5ce9fa30c3a3207a298ad96c1a1f6aa5d6f1b1256fc596f6f2f0020
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Security for cognisn-konfig 0.5.0rc1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cognisn_konfig-0.5.0rc1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page