Skip to main content

Notifig

A highly declarative, strictly typed, reactive config

Notifig is a configuration library built on Pydantic, and strongly rooted on these principles:

Declaration is behavior - The shape of a config field derives its usage.

Validation, serialization, value choices, CLI flags, all follow from writing the field itself. For example, this statement creates a colors field that only accepts certain values and can be set both with comma-separated values (--color "blue,red"") or explicit lists:

from enum import Enum
from typing import Annotated
from pydantic import Field
from notifig import Choice, Delimited, CLIFlags


class Color(Enum):
    RED = "#FF0000"
    GREEN = "#00FF00"
    BLUE = "#0000FF"

COLORS = {name.lower(): color for name, color in Color.__members__.items()}

# Color type with restricted values
ColorType = Annotated[Color, Choice(COLORS)]
# List that can parse/serialize delimited color names (comma by default)
ColorList = Annotated[list[ColorType], Delimited()]
# List of colors with CLI flags
colors: Annotated[
    ColorList,
    CLIFlags(["color", "c"]),  # creates --color/-c CLI flags
] = Field(
    default="green",  # default value
    # info string for --help and CLI errors
    description="Available colors",
)

# Usage
#   YAML: `colors: green,blue`
#   CLI:  `--colors "blue,red"`
Single source of truth - Settings should be declared once, in a single mutable single register.

A common example is mapping CLI flags to their config value, which usually involves maintaining a parallel dict that references fields by string name and needs to be manually kept in sync with the config itself:

class BadSettings:
    foo: str
    bar: str | None = None
    baz: int  # We added baz, but forgot to add its CLI flag below

# If any field gets renamed or deleted, someone has to remember to change it here.
CLI_FLAGS = {
    "foo": "foo",
    "f": "foo",
    "bar": "bar"
}

# Requires merging the CLI data into config fields 
for flag, value in cli_data.items():
    if (field := CLI_FLAGS[flag]):
        setattr(config, field, value)

With Notifig, the CLI flags live on their respective field declarations. Deleting or altering a field and all its flags only touches one statement, in a single place.

class Settings(Config):
    foo: Annotated[str, CLIFlags("foo", "f")] = Field(description="Value of Foo")
    bar: Annotated[str|None, CLIFlags("bar")] = Field(
        description="Name of Bar, if any",
        default=None,
    )
    baz: int = Field(description="Amount of Baz")
Distributed awareness - Each part of an application only interacts with its own config section.

An application's structure hierarchy should map to its config structure. Each component declares its own config section with the fields it needs, and does not need to be

Reactive state - Changes in the config should inform anyone interested.

Adding, changing or deleting an entry should able to trigger behavior instead of relying on periodic checks. An observer is a callable or coroutine registered to a path, and it's called whenever it is altered. A simple example where changing a UI's theme causes it to redraw:

from typing import Annotated
from pydantic import Field
from notifig import Config, ConfigSection, ConfigChange, Choice

class UIConfig(ConfigSection):
    theme: Annotated[str, Choice(["dark", "light"])] = Field(default="light")

class Settings(Config):
    ui: UIConfig = Field(default_factory=UIConfig)

config = Settings()

# sync observer that logs every change
@config.on_change()
def print_changes(section: ConfigSection, changes: tuple[ConfigChange]):
    for change in changes:
        print(f"Change of type {change.__class__.__name__} on {change.path}")

# Simple assignment works for sync observers
config.ui.theme = "dark"
config.ui.theme = "light"
        
# async observer that redraws UI theme
@config.on_change("ui.theme")
async def redraw_theme(section: ConfigSection, changes: tuple[ConfigChange]):
    await interface.update_theme(section.ui.theme)

# Async observers require `await` to be called
await config.ui.set_and_wait(theme="dark")

Install

pip install notifig

Requires Python ≥ 3.13.

Features

  • Custom annotations - Notifig introduces several custom Pydantic annotations to express behavior from types:
    • CLIFlags - adds a shortcut CLI flag for a field
    • Choice - restricts the values a field can take according to a list of options
    • CommaSeparated - allows parsing a list delimited by ,
    • Link - links one field to another through its full path
  • Observers -
  • Static and Dynamic sections
  • Obvious usage - bar = section.foo, section["foo"] = "baz", section.get("foo.bar"), for name, field in section
  • File formats: supports config files in JSON, YAML, TOML, INI and .env

Built on

Metadata

Release files for notifig 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for notifig 0.2.0
File Size Uploaded Provenance
notifig-0.2.0.tar.gz 81.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for notifig 0.2.0
File Interpreter ABI Platform
notifig-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 138.1 kB

Release files / notifig-0.2.0.tar.gz

Download URL notifig-0.2.0.tar.gz
Size 81.2 kB
Tags Source
SHA-256 checksum
How to use checksums
aab6212ca2072b80429751619ee0007065be50dbc1559d9f2e192a4f434a2133
BLAKE2b-256 checksum
How to use checksums
db52e04754b1facc24a6699a5ccd0a4e45e2a1a475e2c446c8881ffe8aebb3b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / notifig-0.2.0-py3-none-any.whl

Download URL notifig-0.2.0-py3-none-any.whl
Size 56.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ee27c7cf6febf27deaa175d0ed775041a8c01dc1b071f76cba204b4478be7940
BLAKE2b-256 checksum
How to use checksums
0501a79a08c5db3a845fcb2a902115857a3666f0f7706cc4d6a7b66be286f94c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for notifig 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for notifig-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page