Simple config package for Python
  • Python 99.4%
  • Makefile 0.6%
Find a file
Renovate ba3e239645
All checks were successful
ci/woodpecker/pr/check-commits Pipeline was successful
ci/woodpecker/pr/checks Pipeline was successful
ci/woodpecker/push/release-prepare Pipeline was successful
chore(deps): update dependency mypy to v2.3.0
2026-07-14 13:22:02 +00:00
.woodpecker ci(deps): update woodpecker python plugins to v4.1.5 2026-07-13 09:14:35 +00:00
src/bs_config feat: allow stacking envs 2025-10-25 22:41:30 +02:00
tests feat: implement Env.get_duration() 2025-10-25 19:05:14 +02:00
.editorconfig Empty project 2023-09-24 20:53:37 +02:00
.gitignore fix: Ignore all cache folders 2024-06-22 22:16:28 +02:00
.mise.toml chore(deps): update uv to v0.11.26 2026-07-01 20:00:05 +00:00
.pre-commit-config.yaml ci(deps): update commitizen to v4.16.4 2026-06-23 12:37:15 +00:00
CHANGELOG.md bump: release version 5.0.2 2026-06-04 16:56:53 +00:00
Makefile chore: fix typing errors 2025-10-23 19:19:36 +02:00
mise.lock chore(deps): lock file maintenance 2026-07-13 08:28:41 +00:00
pyproject.toml chore(deps): update dependency mypy to v2.3.0 2026-07-14 13:22:02 +00:00
README.md docs: update readme 2026-01-16 20:20:20 +01:00
renovate.json chore(renovate): don't pin extras 2026-06-12 15:33:33 +02:00
uv.lock chore(deps): update dependency mypy to v2.3.0 2026-07-14 13:22:02 +00:00

bs-config

Usage

This package provides an Env class for easy access and validation of configuration values from the environment or TOML files.

Example:

from bs_config import Env

env = Env.load()

# a: int | None (missing or blank values lead to the default None)
a = env.get_int("my-int")

# b: int (you specified a default, so it can't be None)
b = env.get_int("my-iny", default=42)

# c: int (if the value is missing, a ValueError is raised)
c = env.get_int("my-int", required=True)

Nested Values

You can access nested values by either separating keys with a dot, or using a scoped Env instance:

from bs_config import Env

env = Env.load()
a = env.get_int("nested.my-int")

nested_env = env / "nested"
b = nested_env.get_int("my-int")

assert a == b

Key Translation

For environment variables and Dotenv values, keys are translated to SCREAMING_SNAKE_CASE. Nested scopes are translated to a double underscore, so the key nested-section.my-value becomes NESTED_SECTION__MY_VALUE.

Dotenv Support

If you install the package with the dotenv extra (pip install bs-config[dotenv]), you can load the contents of .env files in addition to the environment variables from os.environ:

from bs_config import Env

# Includes values from the .env file (if present)
env = Env.load(include_default_dotenv=True)

# Includes values from the test.env and dev.env files (if present)
env = Env.load(additional_dotenvs=["test", "dev"])

TOML Support

You can also load TOML config files into an Env instance. Note that given paths are allowed to not exist, and dotenv/env values take precedence.

from bs_config import Env
from pathlib import Path

env = Env.load(toml_configs=[Path("/etc/myapp/config.toml")])