A configuration manager for Python code.
Configstack is meant to reduce the amount of developer code needed to get a flexible application configuration up and running. It supports layered configuration from model defaults, files, environment variables, and command-line arguments while keeping validation in Pydantic.
| Feature | Supported |
|---|---|
| Supports command line arguments | ✅ |
| Supports environment variables | ✅ |
| Support environment variables from .env files | ✅ |
| Supports YAML configuration files | ✅ |
| Supports JSON configuration files | ✅ |
| Support default values in code | ✅ |
| Type safe configuration values | ✅ |
| Fail early | ✅ |
| Priority based merge of multiple configuration sources | ✅ |
| Easy to use API | ✅ |
| Support for multiple independent config stacks | ✅ |
| Support for nested config files | ❌ |
For more details on the concepts, see docs/concepts.md.
Configstack supports two complementary usage styles.
Use the singleton mode when your application needs one active configuration context for the whole process. This is the most convenient API for scripts, CLIs, and services with one app-wide config.
import configstack as cfg
from configstack import CONFIG
from pydantic import BaseModel
class AppConfig(BaseModel):
some_parameter: str = "default_value_set_in_python_code"
another_parameter: str = "default_value_set_in_python_code"
cfg.setup(AppConfig, cli=True)
print(CONFIG.model_dump())
print(CONFIG.get_source())Example execution:
python app.py --another_parameter set_from_cli
Example output:
{'some_parameter': 'default_value_set_in_python_code', 'another_parameter': 'set_from_cli'}
{'some_parameter': SET_BY_DEFAULT_APP_CONFIG, 'another_parameter': SET_BY_CLI}
Use the instance mode when you need more than one configuration at the same time. This is useful for connectors, clients, plugins, or tests where independent config state must coexist safely in one process.
import configstack as cfg
from pydantic import BaseModel
class ConfigA(BaseModel):
host: str = "https://workspace"
token: str = "default-token"
class ConfigB(BaseModel):
account_name: str = "default-account"
container: str = "default-container"
config_a = cfg.ConfigStack()
config_b = cfg.ConfigStack()
config_a.setup_defaults(ConfigA, token="token-a")
config_b.setup_defaults(ConfigB, container="bronze")
print(config_a.config.token)
print(config_a.source["token"])
print(config_b.config.container)
print(config_b.source["container"])For a full how-to guide, see docs/howto.md.
For details on configuration traceability, see docs/traceability.md.
To install the dependencies for this project, run:
poetry installPytests are available in the tests directory. To run them, execute:
pytestThe project uses bump-my-version configured via pyproject.toml.
To bump a version, run:
bump-my-version bump minorThe repo comes with a demo application in examples/demo.py that demonstrates the library features. To run it, execute:
poetry run python examples\demo.pyJorrit Vander Mynsbrugge