Skip to main content

anycfg

Version Python versions License: MIT Docs CI

anycfg loads, layers and writes configuration in any registered format with the standard Python serialization API — load, loads, dump, dumps, as json and tomllib spell it — plus a Loader that merges many sources in order, YAML !include, typed hydration, and a trust policy that is untrusted by default. Documentation: https://jose-pr.github.io/anycfg/.

anycfg was published as yaconfiglib up to 0.13.1; see Migrating from yaconfiglib.

Features

  • One vocabulary. load(path) and dump(obj, path) pick the format from the file extension, so dump(x, "a.json") then load("a.json") round-trips; loads(text, format=...) and dumps(obj, format=...) take content. An extension no format claims is an error, never a guess.
  • Formats as plugins. JSON, YAML, TOML, INI and dotenv are built in; a Format subclass registers in code or through the anycfg.formats entry-point group. Every format passes the shipped contract suite (anycfg.testing.FormatContract).
  • Layering. Loader(merge="deep").load("base.yaml", "conf.d/*.yaml", "local.toml") merges in order, with deterministic glob ordering, simple, substitute or deep strategies (or your own), DELETE to remove a key, and collect= to gather documents instead.
  • Sources beyond files. Any pathapi Path, open files, Python mappings, the environment (sources.Env), in-memory text (sources.Text) and commands (cmd+json://..., script files).
  • Includes. !include in YAML, file-relative at every depth, with cycle detection and a load budget.
  • Typed results. load(..., into=Model) builds a dataclass, a Pydantic model or any class, coercing every field without losing data.
  • Templates. Loader(interpolate=True) renders {{ ... }} in values after merging — or interpolate="liquid" (any tplx engine), or interpolate="vars" for ${a.b} references with no extra; a file named app.yaml.j2 (any engine's suffix) is rendered whole before parsing.
  • Async. await aload(...), aload_all, adump and Loader.aload read async streams and chunk iterators (stopping past the byte budget) and run the rest of the load off the event loop; no extra needed.
  • Safe by default. Commands and templates are off, interpolation is sandboxed, includes can be confined to directories, and errors never carry document text.

Installation

pip install anycfg

pathapi is installed with it. Extras:

Extra Adds Needed for
yaml PyYAML 6 the YAML format and !include
toml tomli-w writing TOML (reading needs no extra: tomli comes with anycfg below Python 3.11)
templates tplx[jinja] interpolation and template files
all every extra above

import anycfg imports none of them; a feature whose extra is missing raises MissingDependencyError naming it.

Quick start

One document:

import anycfg

config = anycfg.load("settings.yaml")          # format from the extension
data = anycfg.loads('{"a": 1}', format="json")
anycfg.dump(config, "settings.json")           # written as JSON

A few layers, later over earlier, None for one that is absent:

config = anycfg.load("base.toml", "local.toml", merge="deep")
config = anycfg.load(*anycfg.default_configs("app.toml"), default={})

Layers, with dot access:

from anycfg import Loader

loader = Loader(base_dir="conf", merge="deep", wrap=True)
config = loader.load("base.yaml", "conf.d/*.yaml", "local.toml", None)
print(config.database.host)

Typed:

import dataclasses
import anycfg

@dataclasses.dataclass
class Database:
    host: str
    port: int

db = anycfg.load("db.json", into=Database)     # "5432" becomes 5432

Includes and interpolation, in app.yaml:

base: /srv/app
logs: "{{ base }}/logs"
database: !include db.yaml
config = Loader(interpolate=True).load("app.yaml")

The environment and commands, which you opt into:

from anycfg import Loader, Policy
from anycfg.sources import Env

config = Loader(policy=Policy.trusted()).load(
    "base.yaml",
    "cmd+json://vault kv get -format=json secret/app",
    Env("APP_", nested="__"),                       # APP_DB__PORT -> {"DB": {"PORT": ...}}
)

API overview

Module Purpose
anycfg load, loads, load_all, loads_all, dump, dumps; aload, aload_all, adump; Loader, Policy; user_config_path, system_config_path, default_configs; merging (DELETE, register_merge); hydrate, typed_merge; DotAccessibleDict; interpolation; every exception
anycfg.formats the Format contract and the registry: register_format, get, for_filename, names
anycfg.sources Source, Text, Chunks, Data, Env, Command, and the scheme registry
anycfg.testing FormatContract, the suite every format passes

The installed package carries its API header, anycfg/AGENTS.md.

Trust policy

A load reads only what you named, parses it, and follows !include. Anything else must be allowed by its Policy:

Setting Default Allows
allow_commands off command sources and script files
allow_templates off template files
allow_includes on !include / !load
sandbox on interpolation and template files in tplx's sandbox; engines it cannot hold refused
confine_to none every file read inside these directories
max_includes, max_depth, max_bytes 1000, 64, 64 MiB the load's budget

Policy.trusted() turns commands and templates on and the sandbox off, for configuration you wrote yourself. For configuration you did not write, keep the default and set confine_to.

Development

# One venv per interpreter, named <version>-<os>-<arch>:
py -3.9 -m venv .venv/3.9-nt-amd64

# The dev extra installs the tooling and every extra that has tests:
.venv/3.9-nt-amd64/Scripts/pip install -e ".[dev]"

# Put the venv's Scripts (bin on POSIX) first on PATH: command tests start `python`.
export PATH="$PWD/.venv/3.9-nt-amd64/Scripts:$PATH"

python -m pytest -q -rs

AGENTS.md is the orientation file for a checkout: layout, environments, CI and the release procedure. Micro-benchmarks live in benchmarks/.

Releasing

The project follows Semantic Versioning and keeps a changelog. Pushing a v* tag runs the release workflow: test gate, build, GitHub release, PyPI publish; the docs site is deployed after it.

License

MIT — see LICENSE.

Metadata

Release files for anycfg 0.15.1

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

Source distribution (sdist)

Source distribution for anycfg 0.15.1
File Size Uploaded Provenance
anycfg-0.15.1.tar.gz 306.4 kB With provenance Details

Built distribution (wheel)

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

Total release size: 440.0 kB

Release files / anycfg-0.15.1.tar.gz

Download URL anycfg-0.15.1.tar.gz
Size 306.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2514962e135d03bf55c04bce00cad9a3158400b0f80b263c7cb736cb9d952d1d
BLAKE2b-256 checksum
How to use checksums
4302b929ec1aedf8915b1d24682c535a3e686f288add9fc203d686bec7668677
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 20, 2026.

Transparency log

Release files / anycfg-0.15.1-py3-none-any.whl

Download URL anycfg-0.15.1-py3-none-any.whl
Size 133.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1d09623794c320b314a2ea510d7a33e8a8732cef39577b6beb41f65faea12ace
BLAKE2b-256 checksum
How to use checksums
eb0d234ac88994921e4afb8e72dbfddd3a821c9efc3bf21bf30d5f5bf9e6b06d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 20, 2026.

Transparency log

Security for anycfg 0.15.1

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 anycfg-0.15.1.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 20, 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.

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