What's YadOpt?
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 to create beautiful command-line interfaces, just like docopt and docopt-ng, however, YadOpt also supports: (1) date type hinting, (2) conversion to dictionaries and namedtuples, and (3) saving and loading 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 arg
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 arg
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 of YadOpt repository.
Installation
Please install from pip.
$ pip install yadopt
Usage
Use yadopt.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
args = yadopt.parse(__doc__)
# Parse the given argv.
args = yadopt.parse(__doc__, argv)
Use yadopt.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, real_arg: str):
...
if __name__ == "__main__":
main("real argument")
Dictionary and namedtuple support
The returned value of yadopt.parse is an instance of YadOptArgs that is a normal mutable Python class. However, sometimes a dictionary that has the get accessor, or an immutable namedtuple, may be preferable. In that case, please try .to_dict and .to_namedtuple functions.
# Convert the returned value to dictionary.
args = yadopt.parse(__doc__).to_dict()
# Convert the returned value to namedtuple.
args = yadopt.parse(__doc__).to_namedtuple()
Restore arguments from a text file
YadOpt has a function to save parsed argument instances as a text file, and to restore the argument instances from the text files. These functions probably be useful when recalling the same arguments that previously executed, for example, machine learning code.
# At first, create a parsed arguments (i.e. YadOptArgs instance).
args = yadopt.parse(__doc__)
# Save the parsed arguments as a text file.
yadopt.save("args.txt", args)
# Resotre parsed YadOptArgs instance from the JSON file.
args_restored = yadopt.load("args.txt")
# The restored arguments are the same as the original.
assert args == args_restored
The format of the text file is straightforward — just exactly what you would type on a command line under the normal use case. If you want to write the text file manually, the author recommends making a text file using the save
function and investigating the contents of the file at first.
Type hints
One of the features of YadOpt is that users can provide type hints to arguments and options. For example, if an option --opt
is defined as --opt INT
, then the value of --opt
is parsed as an integer. There are several ways to provide type hints to arguments and options, we list them all below with minimal example code.
1. Type hints for arguments
1.1 Parentheses rule
If a description begins with parentheses, the content within the parentheses is treated as a type name, and the argument value is converted to the specified type. Note that the argument value is kept as a string if the specified type name is invalid.
"""
Usage:
sample.py <arg>
Options:
arg (int) Integer argument.
"""
import yadopt
args = yadopt.parse(__doc__)
assert isinstance(args.arg, int)
1.2 Postfix rule for argument name
Another way to provide type hints to arguments is adding type name at the end of argument names. For example, argument x_int
is parsed as an integer value.
"""
Usage:
sample.py <arg_int>
Options:
arg_int Integer argument.
"""
import yadopt
args = yadopt.parse(__doc__)
assert isinstance(args.arg_int, int)
2. Type hints for options
2.1 Parentheses rule
The same as the parentheses rule for arguments.
"""
Usage:
sample.py [--opt VALUE]
Options:
--opt VALUE (int) Integer option.
"""
import yadopt
args = yadopt.parse(__doc__)
assert isinstance(args.opt, int)
2.2 Postfix rule for option value name
The prefix rules also work for option arguments. However, please note that the type name should be added at the end of the option value name, not the option name. You'll see this form of type hinting most often in code examples.
"""
Usage:
sample.py [--opt INT]
Options:
--opt INT Integer option.
"""
import yadopt
args = yadopt.parse(__doc__)
assert isinstance(args.opt, int)
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 |
API reference
Contents
yadopt.parse
def yadopt.parse(docstr: str,
argv: list[str] = None,
default_type: Callable = None,
force_continue: bool = False) -> YadOptArgs:
Parse docstring and returns YadoptArgs instance.
Args
Name | Type | Default value | Description |
---|---|---|---|
docstr |
str |
- | A help message string that will be parsed to create an object of command line arguments. We recommend to write a help message in the docstring of your Python script and use __doc__ here. |
argv |
list[str] |
None |
An argument vector to be parsed. YadOpt uses the command line arguments passed to your Python script, sys.argv[1:] , by default. |
default_type |
Callable |
None |
A function that assign types to arguments and option values. The default value None means using default function. |
force_continue |
bool |
False |
If True , do not exit the software regardless of whether YadOpt succeeds command line parsing or not. |
Returns
Type | Description |
---|---|
YadOptArgs |
The returned value is an instance of the YadOptArgs class that represents parsed command line arguments. The YadOptArgs class is a normal mutable Python class and users can access to parsed command line arguments by the dot notation. If you wish to convert YadOptArgs to dictionary type, please use .to_dict() function. Likewise, if you prefer an immutable data type, please try .to_namedtuple() function. |
yadopt.wrap
def yadopt.wrap(*pargs: list, **kwargs: dict) -> Callable:
Wrapper function for the command line parsing.
Args
The same as the arguments of yadopt.parse
function.
Returns
Type | Description |
---|---|
Callable |
The yadopt.wrap is a Python decorator function that allows users to modify the behavior of functions or methods, therefore the returned value of this function is a callable object. The first argument of the target function of this decorator is curried by the result of yadopt.parse and the curried object will be returned. |
yadopt.to_dict
def to_dict(args: YadOptArgs) -> dict:
Convert YadOptArgs
instance to a dictionary.
Args
Name | Type | Default value | Description |
---|---|---|---|
args |
YadOptArgs |
- | Parsed command line arguments. |
Returns
Type | Description |
---|---|
dict |
Dictionary of the given parsed arguments. |
yadopt.to_namedtuple
def to_namedtuple(args: YadOptArgs) -> collections.namedtuple:
Convert YadOptArgs instance to a named tuple.
Args
Name | Type | Default value | Description |
---|---|---|---|
args |
YadOptArgs |
- | Parsed command line arguments. |
Returns
Type | Description |
---|---|
collections.namedtuple |
Namedtuple of the given parsed arguments. |
yadopt.save
def save(path: str, args: YadOptArgs) -> None:
Save the parsed command line arguments as a text file.
Args
Name | Type | Default value | Description |
---|---|---|---|
path |
str |
- | Destination path. |
args |
YadOptArgs |
- | Parsed command line arguments to be saved. |
Returns
Type | Description |
---|---|
None |
- |
yadopt.load
def load(path: str, docstr: str = None) -> YadOptArgs:
Load a parsed command line arguments from text file.
Args
Name | Type | Default value | Description |
---|---|---|---|
path |
str |
- | Source path. |
Returns
Type | Description |
---|---|
YadOptArgs |
Restored parsed command line arguments. |