Typed, layered configuration for Python evaluations and experiments
Project description
lunaconf
lunaconf is a small configuration library for evaluations and experiments. It combines Pydantic models with ordered configuration layers from nested CLI assignments, JSON, TOML, environment-backed values, and argument files.
It supports Python 3.11 and newer.
Installation
pip install lunaconf
Define a configuration
from typing import Self
from pydantic import Field
from lunaconf import LunaConf
class Config(LunaConf):
required: int
batch_size: int = 8
model: str = "example/model"
temperatures: list[float] = Field(default_factory=lambda: [0.0, 0.7])
@classmethod
def __lunaconf_default__(cls) -> Self:
return cls(required=42)
LunaConf subclasses pydantic.BaseModel, so normal Pydantic validation, aliases, validators, nested models, and serialization options remain available. When aliases are defined, lunaconf uses the alias names in its mutable configuration dictionary and CLI paths.
Override __lunaconf_default__ when the model contains required fields or needs application-specific defaults.
Build from command-line layers
from lunaconf import lunaconf_cli
config = lunaconf_cli(Config)
Nested fields and list indices use dot-separated paths. Numeric components address list indices; other non-empty components address dictionary keys, including names such as model-id:
python example.py batch_size=16 temperatures.1=0.5
python example.py 'model=another/model'
python example.py 'endpoint=https://example.test?a=1&b=2'
Values are parsed as JSON when possible. Otherwise they remain strings.
Multiple assignments can be separated with semicolons. A semicolon inside a quoted JSON string remains part of the value:
python example.py 'batch_size=16;model=another/model'
python example.py 'message="first; second";batch_size=16'
Structured configuration sources
Sources are applied in command-line order, so later values override earlier values.
python example.py -J base.json -T machine.toml batch_size=32
Available sources:
-j JSON/-J FILE: JSON object or JSON file.-t TOML/-T FILE: TOML document or TOML file.-d DATA/-D FILE: detect JSON first, then TOML.-C FILE: argument file containing commands and source options.- positional
path=value: nested assignment.
The top level of JSON and TOML input must be an object/table.
List behavior
Structured configuration sources replace lists as a whole while dictionaries merge recursively:
# default values: [1, 2, 3]
config = lunaconf_cli(Config, ["-j", '{"values": [9]}'])
# values == [9]
Use a positional index assignment when only one existing list element should change:
python example.py values.1=9
Argument files
An argument file is parsed with shell-like quoting. Blank lines and comments are ignored.
# config.args
-J "base config.json"
-T machine.toml
message="hello; world # literal"
batch_size=32 # trailing comment
Apply it with:
python example.py -C config.args
Special values
Special values are case-insensitive:
<null>becomesNone.<del>deletes a dictionary field or list element.<inf>,<-inf>, and<nan>become non-finite floats.<env:NAME>reads an environment variable as a string.<envint:NAME>reads an environment variable and converts it toint.
Missing environment variables and invalid integer conversions raise ValueError.
When serializing, unsupported JSON/TOML values are represented using the same markers. Pydantic JSON mode is used so values such as Path, dates, URLs, and enums are converted to portable values first.
Lower-level API
lunaconf_gendict applies the same ordered source logic to an existing dictionary and can extend an existing argparse.ArgumentParser:
import argparse
from lunaconf import lunaconf_gendict
parser = argparse.ArgumentParser()
parser.add_argument("--dry-run", action="store_true")
raw = {"batch_size": 8}
namespace = lunaconf_gendict(raw, parser=parser)
Printing resolved configuration
lunaconf_cli provides:
-p: print JSON and exit.-P: print TOML and exit.-a: include fields whose values equal their defaults.--json-indent N: control JSON indentation.
Development
The repository uses uv, Ruff, strict Pyright, pytest with branch coverage, pre-commit, and GitHub Actions.
uv sync --locked --group dev
uv run pre-commit install
just check
The CI matrix tests Python 3.11 and 3.12. Static analysis targets Python 3.11 syntax and behavior.
Releases
Tags matching v* trigger .github/workflows/release.yml. The workflow:
- verifies that the tag matches
project.version; - runs formatting, linting, strict type checking, and tests;
- removes old build artifacts and runs
uv build --no-sources; - smoke-tests both the wheel and source distribution in isolated environments;
- publishes with
uv publishthrough PyPI Trusted Publishing.
No long-lived PyPI API token is required. The PyPI project must trust:
- owner:
rijuyuezhu - repository:
lunaconf - workflow:
release.yml - GitHub environment:
pypi
The matching GitHub environment must also be created under Settings → Environments → pypi. Requiring manual approval for that environment is recommended.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lunaconf-0.6.0.tar.gz.
File metadata
- Download URL: lunaconf-0.6.0.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
420f9b6b3b41bb0ea0d9f5f2101db43c3bb926117554cf4114a08e8bef608074
|
|
| MD5 |
3697fbe2be1a600b21231f3a9edbf453
|
|
| BLAKE2b-256 |
3381a0ac6f39c0e924da3b008c392b82195dd4df6952f3888a893676f032bd24
|
File details
Details for the file lunaconf-0.6.0-py3-none-any.whl.
File metadata
- Download URL: lunaconf-0.6.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4c4fcf294f225c1c627f931267229dc70782fdecef8e1292d29657e162e3faa
|
|
| MD5 |
bc9bb61a4cebe5df2af02e23687d2bd1
|
|
| BLAKE2b-256 |
549c4073f987989a4558c77a3556cfd213a12d74357c2f8c7537e43203f631af
|