configzen
configzen copied to clipboard
Manage configuration with pydantic.
configzen

Manage configuration with pydantic.
[!Warning] configzen is currently under huge refactoring to work with pydantic v2. The API is subject to change.
It's important to keep your configuration safe and consistent. Give a shot to configzen, because it:
⭐ Supports Python 3.8 or above,
⭐ Is fully typed,
⭐ Supports YAML, JSON, TOML, INI and Plist,
⭐ Supports reading and writing configuration files, fully or partially, with the ability to preserve the original file structure and comments,
⭐ Supports modular configuration with type validation (wrapping runtime Python modules in-place and outside them),
⭐ Supports synchronous and asynchronous file operations,
⭐ Supports loading configuration from environment variables and secret files.
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.
Features
Managing content
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 BaseConfiguration, Field, ModelConfig
class DBConfig(BaseConfiguration):
host: IPv4Address | IPv6Address
port: int
user: str
password: str = Field(exclude=True)
model_config = ModelConfig(
configuration_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
Modular configuration
Wrapping modules in-place
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):
...
Wrapping interchangeable modules
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
Supported file formats
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 | - | xml |
plistlib (standard library) |
Installation
You might simply install it with pip:
pip install configzen
If you use Poetry, then you might want to run:
poetry add configzen
For contributors
[!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 poetryIf 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 installNext 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! ❤️
Legal info
© Copyright by Bartosz Sławecki (@bswck).
This software is licensed under the terms of GPL-3.0 License.