bswck / configzen

Manage configuration with pydantic.

Home Page:https://bswck.github.io/configzen/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

configzen skeleton

Package version Supported Python versions

Tests Coverage Poetry Ruff License Pre-commit

An advanced configuration library for Python.

Warning

configzen is currently under huge refactoring to work with pydantic v2. The API is subject to change.

configzen – easily create and maintain complex, statically-typed configurations with validation in Python.

It's important to keep your configuration safe and consistent. Give a shot to configzen 🚀

⭐ 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:

  1. Without writing a model class:
# config.py
from configzen import ConfigModule

# Annotate config fields
HOST: str = "localhost"
PORT: int = 8000

ConfigModule.wrap_this_module()
  1. 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 xml (standard library)

Installation

You might simply install it with pip:

pip install configzen

If you use Poetry, then 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.

  1. Fork the configzen repository on GitHub.

  2. 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
  3. 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 --hook-type pre-commit --hook-type pre-push

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 MIT License.