Manage configuration with pydantic.
Warning
configzen is currently under huge refactoring to work with pydantic v2. The API is subject to change.
While being built on top of pydantic, configzen inherits most of its features, including data validation, schema generation, custom data types, good integration with Rich, and more.
Learn more below.
Having a YAML configuration file like this:
# database.yml
host: 127.0.0.1
port: 5432
user: postgres
You can create a configzen configuration model for it like this:
# model.py
from ipaddress import IPv4Address, IPv6Address
from configzen import BaseConfig, Field, ModelConfig
class DBConfig(BaseConfig):
host: IPv4Address | IPv6Address
port: int
user: str
password: str = Field(exclude=True)
model_config = ModelConfig(
config_source="database.yml",
env_prefix="DB_",
)
db_config = DBConfig.load()
And you can load your configuration from a file as well as from the environment variables
DB_HOST
, DB_PORT
, DB_USER
and DB_PASSWORD
. Since password
is a field created with
the option exclude=True
, it will not be included in the configuration's exported data: that
guarantees that your password does never leak into database.yml
on save – but you may still pass it
through an environment variable (here – the mentioned DB_PASSWORD
). Secret files are also supported,
see the pydantic documentation
for more information.
pydantic will naturally take care of parsing and validating the loaded data.
Configuration models inherit from the pydantic.BaseSettings
class, so you can use all of its features:
schema generation, type conversion, validation, etc.
There are additional features brought to you by configzen worth checking out, though.
You can use the db_config
object defined above to access the configuration values:
>>> db_config.host
IPv4Address('127.0.0.1')
modify them, if the pydantic model validation allows
it (<Your model>.Config.validate_assignment
will
be True
by default):
>>> db_config.host = "0.0.0.0"
>>> db_config.host
IPv4Address('0.0.0.0')
as well as reload particular values, without touching the rest of the configuration:
>>> db_config.at(DBConfig.port).reload()
5432
# `DBConfig.port` is a LinkedRoute object that ensures `port` of `DBConfig` exists!
>>> db_config
DatabaseConfig(host=IPv4Address('0.0.0.0'), port=5432, user='postgres', password='password')
>>> db_config.at(DBConfig.host).reload()
IPv4Address('127.0.0.1')
>>> db_config
DatabaseConfig(host=IPv4Address('127.0.0.1'), port=5432, user='postgres', password='password')
or reload the whole configuration:
>>> db_config.port = 1234
>>> db_config.reload()
DatabaseConfig(host=IPv4Address('127.0.0.1'), port=5432, user='postgres', password='password')
or save a particular value, without touching the rest of the configuration:
>>> db_config.host = "0.0.0.0"
>>> db_config.port = 443
>>> db_config
DatabaseConfig(host=IPv4Address('0.0.0.0'), port=443, user='postgres', password='password')
>>> db_config.at(DBConfig.host).save()
40
>>> db_config.reload()
DatabaseConfig(host=IPv4Address('0.0.0.0'), port=5432, user='postgres', password='password')
or save the whole configuration:
>>> db_config.save()
39
You can wrap modules in-place with configuration models:
- Without writing a model class:
# config.py
from configzen import ConfigModule
# Annotate config fields
HOST: str = "localhost"
PORT: int = 8000
ConfigModule.wrap_this_module()
- With a model class:
# config.py
from configzen import ConfigModel
# Annotations are optional
HOST = "localhost"
PORT = 8000
class AppConfig(ConfigModel):
HOST: str
PORT: int
AppConfig.wrap_this_module()
Now values HOST
and PORT
will be validated as str
and int
data types, respectively:
>>> import config # <configuration module 'config' from 'config.py'>
>>> config.HOST
'localhost'
>>> config.PORT
8000
>>> config.PORT = "8000"
>>> config.PORT
8000
>>> config.PORT = "abc"
Traceback (most recent call last):
...
You can wrap modules outside them with configuration models:
# setup.py
from configzen import ConfigModel
class AppConfig(ConfigModel):
HOST: str = "localhost"
PORT: int = 8000
config_model = AppConfig.wrap_module("config")
# config.py
HOST: str = "0.0.0.0"
PORT: int = 443
>>> from setup import config_model
>>> config_model.HOST
'0.0.0.0'
>>> config_model.PORT
443
>>> config_model.PORT = "8000"
>>> config_model.PORT
8000
>>> import config
>>> config.HOST
'0.0.0.0'
>>> config.PORT
8000
The following table shows the supported file formats, their requirements, file extensions, and the backend libraries used to accomplish this goal.
File Format | To use, install: | Recognized File Extension(s) | Backend Library |
---|---|---|---|
JSON | - | json |
json (standard library) |
TOML | - | toml , ini , cfg , conf |
tomlkit |
YAML | - | yaml , yml |
ruamel.yaml |
Plist | - | plist |
plistlib (standard library) |
Available as part of the Tidelift Subscription. This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. Learn more here. |
---|
To report a security vulnerability, please use the
Tidelift security contact.
Tidelift will coordinate the fix and disclosure.
You might simply install it with pip:
pip install configzen
If you use Poetry, then you might want to run:
poetry add configzen
Note
If you use Windows, it is highly recommended to complete the installation in the way presented below through WSL2.
-
Fork the configzen repository on GitHub.
-
Install Poetry.
Poetry is an amazing tool for managing dependencies & virtual environments, building packages and publishing them. You might use pipx to install it globally (recommended):pipx install poetry
If you encounter any problems, refer to the official documentation for the most up-to-date installation instructions.
Be sure to have Python 3.8 installed—if you use pyenv, simply run:
pyenv install 3.8
-
Clone your fork locally and install dependencies.
git clone https://github.com/your-username/configzen path/to/configzen cd path/to/configzen poetry env use $(cat .python-version) poetry install
Next up, simply activate the virtual environment and install pre-commit hooks:
poetry shell pre-commit install
For more information on how to contribute, check out CONTRIBUTING.md.
Always happy to accept contributions! ❤️
© Copyright by Bartosz Sławecki (@bswck).
This software is licensed under the terms of GPL-3.0 License.