Skip to main content

Yet another docopt, a human-friendly command line arguments parser.

Project description

     

YadOpt - Yet another docopt

YadOpt is a Python re-implementation of docopt and docopt-ng, a human-friendly command-line argument parser with type hinting and utility functions. YadOpt helps you creating beautiful command-line interfaces, just like docopt and docopt-ng. However, YadOpt also supports (1) date type hinting, (2) conversion to dictionaries and named tuples, and (3) save and load functions.

The following is the typical usage of YadOpt:

"""
Usage:
    train.py <config_path> [--epochs INT] [--model STR] [--lr FLT]
    train.py --help

Train a neural network model.

Arguments:
    config_path     Path to config file.

Training options:
    --epochs INT    The number of training epochs.   [default: 100]
    --model STR     Neural network model name.       [default: mlp]
    --lr FLT        Learning rate.                   [default: 1.0E-3]

Other options:
    -h, --help      Show this help message and exit.
"""

import yadopt

if __name__ == "__main__":
    args = yadopt.parse(__doc__)
    print(args)

Please save the above code as sample.py and run it as follows:

$ python3 sample.py config.toml --epochs 10 --model=cnn
YadOptArgs(config_path=config.toml, epochs=10, model=cnn, lr=0.001, help=False)

In the above code, the parsed command-line arguments are stored in the args variable, and you can access each argument using dot notation, like arg.config_path. Also, the parsed command-line arguments are typed, in other words, the args variable satisfies the following assertions:

assert isinstance(args.config_path, pathlib.Path)
assert isinstance(args.epochs, int)
assert isinstance(args.model, str)
assert isinstance(args.lr, float)
assert isinstance(args.help, bool)

More realistic examples can be found in the examples directory.

Installation

Please install from pip.

$ pip install yadopt

Usage

Use parse function

The yadopt.parse function allows you to parse command-line arguments based on your docstring. The function is designed to parse sys.argv by default, but you can explicitly specify the argument vector by using the second argument of the function, just like as follows:

# Parse "sys.argv" (default behaviour).
args = yadopt.parse(__doc__)

# Parse the given argument vector "argv".
args = yadopt.parse(__doc__, argv)

Use wrap function

YadOpt supports the decorator approach for command-line parsing by the decorator @yadopt.wrap which takes the same arguments as the function yadopt.parse.

@yadopt.wrap(__doc__)
def main(args: yadopt.YadOptArgs, arg1: int, arg2: str):
    ...

if __name__ == "__main__":
    main(arg1=1, arg2="2")

How to type arguments and options

YadOpt provides two ways to type arguments and options: (1) type name postfix and (2) description head declaration.

(1) Type name postfix: Users can type arguments and options by adding a type name at the end of the arguments/options name, such as the following:

Options:
    --opt1 FLT    Option of float type.
    --opt2 STR    Option of string type.

(2) Description head declaration: An alternative way to type arguments and options is to precede the description with the type name in parentheses.

Options:
    --opt1 VAL1    (float) Option of float type.
    --opt2 VAL2    (str)   Option of string type.

The following is the list of available type names.

Data type in Python Type name in YadOpt
bool bool, BOOL, boolean, BOOLEAN
int int, INT, integer, INTEGER
float flt, FLT, float FLOAT
str str, STR, string, STRING
pathlib.Path path, PATH

Dictionary and named tuple support

The returned value of yadopt.parse is an instance of YadOptArgs, a regular mutable Python class. However, sometimes a dictionary with the get accessor, or an immutable named tuple, may be preferable. In such cases, please try yadopt.to_dict or yadopt.to_namedtuple function.

# Convert the returned value to dictionary.
args = yadopt.to_dict(yadopt.parse(__doc__))

# Convert the returned value to namedtuple.
args = yadopt.to_namedtuple(yadopt.parse(__doc__))

Restore arguments from a file

YadOpt has the ability to save parsed argument instances to a file and restore them from the file. These features are useful, for example, in machine learning code, when you want to call exactly the same arguments again after a previous execution. Supported file formats include TOML and JSON.

# At first, create a parsed arguments (i.e. YadOptArgs instance).
args = yadopt.parse(__doc__)

# Save the parsed arguments as a TOML file.
yadopt.save("args.toml", args)

# Resotre parsed YadOptArgs instance from the TOML file.
args_restored = yadopt.load("args.toml")

The format of the TOML and JSON file is pretty straightforward — what the user types on the command line is stored in the "argv" key, and the docstring is stored in the "docstr" key in the TOML/JSON file. If users want to write the TOML/JSON file manually, the author recommends making a TOML/JSON file using the yadopt.save function at first and investigating the contents of the file.

API reference

See API reference page of the online document.

Tips

Merge two YadOptArgs objects

The YadOptArgs class, which is the return value of the yadopt.parse function, supports the merge operator |, similar to Python's dictionary type. This operator combines the two given YadOptArgs objects into a new one. In case of a key conflict, the values from the left-hand operand are used.

This merge operator is particularly useful for implementing a feature to read an existing configuration file (for example, a file specified with the --config argument) and then overwrite those settings with values explicitly provided in the command line arguments. For example:

"""
Usage:
    train.py <config_path> [--epochs INT] [--model STR] [--lr FLT]
    train.py --help

Train a neural network model.

Arguments:
    config_path     Path to base config file.

Training options:
    --epochs INT    The number of training epochs.   [default: 100]
    --model STR     Neural network model name.       [default: mlp]
    --lr FLT        Learning rate.                   [default: 1.0E-3]

Other options:
    -h, --help      Show this help message and exit.
"""

import yadopt

if __name__ == "__main__":

    # Parse the command line arguments.
    args = yadopt.parse(__doc__, ignore_default_values=True)

    # Load the base config file.
    args_base = yadopt.load(args.config_path)

    # Update the parsed command line arguments.
    args_updated = args | args_base
    print(args_updated)

More complex validations for the input command-line arguments

If you want more complex validations for the command-line arguments, the author recommends using Pydantic for the dictionary form of the parsed object generated by YadOpt. Let me explain it using the sample code at the beginning of this README. Suppose you want to constrain the command line argument "lr" such that "0 <= lr <= 1.0". The following code will achieve that:

"""
Usage:
    train.py <config_path> [--epochs INT] [--model STR] [--lr FLT]
    train.py --help

Train a neural network model.

Arguments:
    config_path     Path to config file.

Training options:
    --epochs INT    The number of training epochs.   [default: 100]
    --model STR     Neural network model name.       [default: mlp]
    --lr FLT        Learning rate.                   [default: 1.0E-3]

Other options:
    -h, --help      Show this help message and exit.
"""

import pathlib
import pydantic
import yadopt

class CommandlineArgumentsModel(pydantic.BaseModel):
    """
    Pydantic model for validation.
    """
    config_path: pathlib.Path
    epochs: int
    model: str
    lr: float = pydantic.Field(ge=0.0, le=1.0)

if __name__ == "__main__":

    # Parse command-line arguments using YadOpt.
    args = yadopt.parse(__doc__)

    # Validate using the Pydantic model.
    valid_args = CommandlineArgumentsModel(**yadopt.to_dict(args))
    print(valid_args)

(It might be a good idea to add features to YadOpt that make it easier for users to implement the above code. However, the author hasn't implemented it yet because he wants to keep the dependency of YadOpt small.)

Developer's note

Preparation

Additional commands and Python packages are required for developers to measure the number of lines in the code, code quality, etc. Please run the following command (the author recommends using venv to avoid polluting your development environment).

$ apt install cloc docker.io
$ pip install -r requirements-dev.txt

Utility commands for developers

Utility commands are summarized in the Makefile. Please run make at the root directory of this repository to see the details of the subcommands in the Makefile.

$ make
Usage:
    make <command>

Build commands:
    build         Build package
    testpypi      Upload package to TestPyPi
    pypi          Upload package to PyPi
    install-test  Install from TestPyPi

Test and code check commands:
    check         Check the code quality
    count         Count the lines of code
    coverage      Measure code coverage
	test          Run test on this device
	testall       Run test on Docker

Other commands:
    clean         Cleanup cache files
    help          Show this message

Architecture diagram

software_architecture

Project details


Download files

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

Source Distribution

yadopt-2025.12.13.tar.gz (109.9 kB view details)

Uploaded Source

Built Distribution

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

yadopt-2025.12.13-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file yadopt-2025.12.13.tar.gz.

File metadata

  • Download URL: yadopt-2025.12.13.tar.gz
  • Upload date:
  • Size: 109.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for yadopt-2025.12.13.tar.gz
Algorithm Hash digest
SHA256 4616a9602b2a7e67ee0ca7e87f085e469822b466eee153a2949a04093161968e
MD5 7e031002ca005e027e498a6834ddb575
BLAKE2b-256 23f676228167d6fd08bea40b91fb2286894a4ea1238308c060c63bf82d60b0b2

See more details on using hashes here.

File details

Details for the file yadopt-2025.12.13-py3-none-any.whl.

File metadata

  • Download URL: yadopt-2025.12.13-py3-none-any.whl
  • Upload date:
  • Size: 31.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for yadopt-2025.12.13-py3-none-any.whl
Algorithm Hash digest
SHA256 4c95148a37db8481c9317981972c7767f80553bbee3361551057a9d4ceee32bf
MD5 4693b802227a1767caccb9492a285d6c
BLAKE2b-256 c539cee60a0e435d9bdea68fc498689796c25ddbbee9c9b259671750f36d33d9

See more details on using hashes here.

Supported by

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