Skip to main content

TomlArg

A unified TOML + CLI parser for configurable Python projects. Every TOML key-value pair becomes a command-line flag with a default value.

tomlarg exposes an ArgumentParser which subclasses argparse.ArgumentParser to allow drop-in replacement - extending support for reading TOML files and keeping argument parsing functionality.

Features

  • Multiple TOML sources from file, string, or already-parsed dict.
  • Tables flattened into dotted flags (--db.pool.size) at any depth.
  • Arrays of tables index-addressable (--servers.1.port).
  • Values typed from the TOML: strings, integers, floats, booleans, datetimes, dates, times and arrays.
  • No dependencies.
  • For Python >=3.12.

Install

pip install tomlarg

Quickstart

# config.toml
name = "myapp"
port = 8080
debug = false
tags = ["web", "api"]

[db]
host = "localhost"

[db.pool]
size = 5

[[servers]]
host = "s1"
port = 8001

[[servers]]
host = "s2"
port = 8002
# main.py
import tomlarg

parser = tomlarg.ArgumentParser(toml_file="config.toml")

args = parser.parse_args()

args.name  # 'myapp'
args.db.pool.size  # 5
args.servers[1].port  # 8002
dict(args)  # the whole tree as plain data
$ python3 main.py --db.pool.size 50 --tags x,y --no-debug

Usage

TOML Flag Read back as
port = 8080 --port args.port
[db] host = "x" --db.host args.db.host
[db.pool] size = 5 --db.pool.size args.db.pool.size
[[servers]] port = 1 --servers.0.port args.servers[0].port
debug = false --debug / --no-debug args.debug
tags = ["a"] --tags a,b,c args.tags

Types come from the TOML value, so --port takes an integer, --updated takes a datetime, and --tags takes a comma-separated list whose element type is inferred. --tags= or a bare --tags gives an empty list.

API

ArgumentParser(*args, toml_file=None, toml_str=None, toml_dict=None, delimiter=".", **kwargs)

Takes everything argparse.ArgumentParser takes. The three TOML arguments are shorthand for the add_toml* methods below, applied in the order listed.

parser = tomlarg.ArgumentParser(prog="myapp", toml_file="config.toml")

delimiter sets the separator used for generated flags and for reading values back. Results stay nested whichever separator is chosen.

parser = tomlarg.ArgumentParser(delimiter="__", toml_file="config.toml")
parser.parse_args(["--db__pool__size", "50"]).db.pool.size  # 50

add_toml(path)

Record a TOML file, given as a Path or str. A missing file raises FileNotFoundError here, not at parse time.

parser.add_toml("profile.toml")

add_toml_str(text)

Record a TOML document. Malformed TOML raises tomllib.TOMLDecodeError here, not at parse time.

parser.add_toml_str("[user]\nname = 'x'")

add_toml_dict(data)

Record already-parsed TOML. data is any Mapping, which is how a table from an enclosing document is passed.

parser.add_toml_dict(pyproject["tool"]["myapp"])

Sources merge in the order added, key by key, so a later source overrides only the leaves it names:

# base.toml                # prod.toml
[db]                       [db]
host = "localhost"         host = "db.internal"
port = 5432
[db.pool]                  [db.pool]
size = 5                   size = 20
timeout = 30
db.host         = 'db.internal'   # from prod
db.port         = 5432            # kept from base
db.pool.size    = 20              # from prod
db.pool.timeout = 30              # kept from base

add_argument(*args, **kwargs)

Inherited from argparse, with the same signature. A flag you declare keeps its type=, help= and everything else, and the TOML value becomes its default. Sources are applied at parse time, so this may be called before or after them.

Declaring a flag for a table stops that table being expanded, which is the escape hatch for passing one whole:

parser.add_argument(
    "--labels", type=json.loads, help="Labels"
)  # --labels '{"env":"dev"}'

parse_args(args=None, namespace=None)

Applies the sources, then parses. Precedence, highest first: command line, TOML, add_argument defaults.

Returns a tomlarg.Namespace, a subclass of argparse.Namespace addressable by delimited path. args.db.pool.size and getattr(args, "db.pool.size") resolve the same value, and dict(args) converts the whole tree back to plain data with arrays of tables as real lists.

parse_known_args(args=None, namespace=None)

As argparse, returning the namespace and the unrecognised arguments.

parser.parse_known_args(["--nope"])  # (Namespace(port=8080), ['--nope'])

format_help() and format_usage()

Apply the sources too, so TOML-derived flags are listed without parsing first.

Examples

Example of overriding --db.host and --servers.1.port flags:

$ python3 examples/basic --db.host db.internal --servers.1.port 9999

Example showing multiple TOML sources can be added:

$ python3 examples/layered

Example of printing help and usage message:

$ python3 examples/basic --help
usage: basic [-h] [--port PORT] [--labels LABELS] [--name NAME] [--debug | --no-debug]
             [--tags [TAGS]] [--updated UPDATED] [--db.host DB.HOST]
             [--db.port DB.PORT] [--db.pool.size DB.POOL.SIZE]
             [--servers.0.host SERVERS.0.HOST] [--servers.0.port SERVERS.0.PORT]
             [--servers.1.host SERVERS.1.HOST] [--servers.1.port SERVERS.1.PORT]

options:
  -h, --help            show this help message and exit
  --port PORT           port to listen on
  --labels LABELS       labels as a JSON object
  --name NAME
  --debug, --no-debug
  --tags [TAGS]
  --updated UPDATED
  --db.host DB.HOST
  ...

See examples.

Errors

Situation Error
Two sources give a key different types cannot replace integer 'port' with string
A key needs a flag another argument owns TOML key 'port' needs --port, which is already taken by an argument storing to 'p'
One dest nests inside another 'db' is both a value and a prefix of 'db.host'
A key is named after a built-in flag TOML key 'help' is the dest of --help, which stores nothing
A value has no command-line spelling unsupported TOML value type for 'when': unknown
A key is empty, or holds the delimiter key '' is empty, so it has no flag
A source is not a mapping TOML data must be a mapping, not list

Todo

  • TOML comment parser to attach argument parameters e.g. choices, required, deprecated.
  • Abbreviating dotted keys (allow_abbrev defaults to false currently).
  • Subparsers.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tomlarg-0.2.1.tar.gz (11.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tomlarg-0.2.1-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file tomlarg-0.2.1.tar.gz.

File metadata

  • Download URL: tomlarg-0.2.1.tar.gz
  • Upload date:
  • Size: 11.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tomlarg-0.2.1.tar.gz
Algorithm Hash digest
SHA256 a302b108d9c6a1907f7d89d2cb71b6ef7879081c7ee65df53b1144d7819ea163
MD5 88f1481db63c6eff253c273baf42ed42
BLAKE2b-256 1fd99ce350f8212e62653eb3a29b2663175f321be9d9d53953cde49a138d9aaa

See more details on using hashes here.

Provenance

The following attestation bundles were made for tomlarg-0.2.1.tar.gz:

Publisher: release.yml on tuppl/tomlarg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tomlarg-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: tomlarg-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tomlarg-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 55a94ebf42b98e01ef26837dbdee7b66e88e3941ec0dc5cfb477af7f6060d9e3
MD5 42710360a4ddf8e9a4fad4fa93d42ca3
BLAKE2b-256 4aabaed034ab01b4d6b3f5fc7e5392def37ae935cca535221e000e6385033c6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tomlarg-0.2.1-py3-none-any.whl:

Publisher: release.yml on tuppl/tomlarg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page