A tiny config loader and CLI framework built around Pydantic models
Project description
NanoArgs
A tiny, opinionated configuration loader and CLI framework built around Pydantic models.
Features
- YAML Configuration Loading — load and merge multiple files with left-to-right precedence
- Smart Imports —
!importwith deep-merging, paths resolved relative to the importing file - Runtime Overrides — JSONPath-like syntax via
--override - Pydantic Validation — automatic validation and type coercion
- Schema Generation —
--print-schemarenders a formatted JSON schema;--print-configdumps the merged result - Rich CLI Interface — styled help, errors, and schema output via Rich
- Subcommands — multi-command CLIs via
Nested; each command owns its own config model - Type Safety — pyright strict, modern Python type hints
Installation
pip install git+https://github.com/cusp-ai-oss/nanoargs.git
Requires Python 3.10+. Dependencies: lark, pydantic, pyyaml, rich, rich-argparse.
Quick Start
from pydantic import BaseModel
from nanoargs import NanoArgs
class Config(BaseModel):
mode: str = "train"
batch_size: int = 32
learning_rate: float = 0.001
config = NanoArgs(Config).parse()
python app.py config.yaml # load a YAML file
python app.py base.yaml exp.yaml # merge multiple files
python app.py config.yaml --override '$.batch_size=128' # JSONPath override
echo 'batch_size: 128' | python app.py - # read from stdin
python app.py --print-schema # inspect the schema
python app.py config.yaml --print-config # inspect merged result
Subcommands
Use Nested to define multi-command CLIs. Fields typed as T | None = None become subcommands:
from nanoargs import NanoArgs, Nested
class TrainConfig(BaseModel):
lr: float = 0.001
epochs: int = 10
class EvalConfig(BaseModel):
checkpoint: str
class CLI(Nested):
verbose: bool = False # pre-command parent field
train: TrainConfig | None = None
evaluate: EvalConfig | None = None
result = NanoArgs(CLI).parse()
python app.py train config.yaml --override '$.lr=0.01'
python app.py --override '$.verbose=true' evaluate config.yaml
python app.py --help # lists available commands
python app.py train --print-schema # schema for a specific command
Nested composes naturally — a field whose type is itself Nested creates a sub-group (app data preprocess config.yaml).
See the Subcommands guide for full details.
Documentation
- Getting Started — full walkthrough
- Configuration Guide — import system, merge rules, override syntax, CLI flags
- Subcommands —
Nestedpatterns, parent fields, multi-level nesting - Path Syntax — JSONPath-like grammar reference
- API Reference
- Changelog
Gotchas
- YAML booleans in config files:
yes,no,on,offare booleans in YAML. Quote them for strings:"yes". This does not affect--overridevalues. - List merging: config file merging replaces lists entirely — it does not append.
- Hyphenated keys:
--overridepaths require bracket syntax:--override '$["learning-rate"]=0.001'. - Negative array indices:
$[-1]works Python-style (last element). Negative slice bounds are also supported:$[-3:],$[:-1]. - Bracket notation quotes: both
$["key"]and$['key']are supported. --print-configwithout config files: prints Pydantic-validated defaults and exits.- Unknown fields: overriding a path that doesn't match any model field is silently ignored by Pydantic.
- Auto-vivification:
$.a.b.c=1creates intermediate dicts for missing keys orNonevalues. @fileresolution: from the CLI,@fileresolves relative to the working directory; inside YAML (!override), relative to the YAML file. Use@@to escape a literal@.
License
Apache 2.0
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 nanoargs-0.1.1.tar.gz.
File metadata
- Download URL: nanoargs-0.1.1.tar.gz
- Upload date:
- Size: 107.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32301f3bddab47c93bff11db2e5f1a12ca56c135fd27f323c2add376bdbf4801
|
|
| MD5 |
f49279aff12668c1d9cc64c3af6b8b28
|
|
| BLAKE2b-256 |
61835f56967f83ee6743f5c8e2afd713cf069d77bb205ca85273a924dfb91871
|
File details
Details for the file nanoargs-0.1.1-py3-none-any.whl.
File metadata
- Download URL: nanoargs-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
917f1500fd001706b926b219c40872c32b68416b3c8ba50fb9a709d597b9a642
|
|
| MD5 |
51b1c0e2861ca2f21d424ef53c22e3ac
|
|
| BLAKE2b-256 |
fdd40ccb1590423d1aa3b4eac633f2f3d0518dadbdbba93cce5e8cea6e52c2e7
|