Tools to create commandline interfaces
This module provides functionality to make creation of CLI (command line interface) tools easier.
In particular, we support the paradigm of one main command, providing access to subcommands, as follows: In the main function of a CLI, e.g. the function exposed as console_scripts entry point, you
add global options and arguments, and
then pass the subparsers when calling
clldutils.clilib.register_subcommands()
,parse the command line
and finally call args.main - which has been set to a subcommand’s run function.
Subcommands must be implemented as Python modules with
a docstring (describing the command)
an optional register(parser) function, to register subcommand-specific arguments
a run(args: argparse.Namespace) function, implementing the command functionality.
A fleshed-out usage example would look like this:
import mycli.commands
def main():
parser, subparsers = get_parser_and_subparsers('mycli')
parser.add_argument(
'-z', '--maxfieldsize',
metavar='FIELD_SIZE_LIMIT',
type=lambda s: csv.field_size_limit(int(s)),
help='Maximum length of a single field in any input CSV file.',
default=csv.field_size_limit(),
)
register_subcommands(subparsers, mycli.commands)
args = parsed_args or parser.parse_args()
if not hasattr(args, "main"):
parser.print_help()
return 1
with contextlib.ExitStack() as stack:
stack.enter_context(Logging(args.log, level=args.log_level))
try:
return args.main(args) or 0
except KeyboardInterrupt:
return 0
except ParserError as e:
print(e)
return main([args._command, '-h'])
with subcommands impemented as modules in the mycli.commands package having the following skeleton:
'''
... describe what the command does ...
'''
def register(parser):
parser.add_argument('--flag')
def run(args):
if args.flag:
pass
- clldutils.clilib.get_parser_and_subparsers(prog, with_defaults_help=True, with_log=True)[source]
Get an argparse.ArgumentParser instance and associated subparsers.
Wraps argparse.ArgumentParser.add_subparsers.
- Parameters:
prog (
str
) – Name of the program, i.e. the main command.with_defaults_help (
bool
) – Whether defaults should be displayed in the help message.with_log (
bool
) – Whether a global option to select log levels should be available.
- Return type:
typing.Tuple
[argparse.ArgumentParser
,typing.Any
]
- clldutils.clilib.register_subcommands(subparsers, pkg, entry_point=None, formatter_class=<class 'clldutils.clilib.Formatter'>, skip_invalid=False)[source]
Register subcommands discovered as modules in a Python package or via entry point.
- Parameters:
subparsers – An object as returned as second item by
get_parser_and_subparsers()
.pkg (
str
) – A Python package in which to look for subcommands.entry_point (
typing.Optional
[str
]) – Name of an entry point group to use for looking up subcommands in other installed packages.formatter_class (
argparse.ArgumentDefaultsHelpFormatter
) – argparse.ArgumentDefaultsHelpFormatter’s subclass to use for help formatting.skip_invalid (
bool
) –
- class clldutils.clilib.PathType(must_exist=True, type=None)[source]
A type to parse pathlib.Path instances from the command line.
Similar to argparse.FileType.
Usage:
def register(parser): parser.add_argument('input', type=PathType(type='file')) def run(args): assert args.input.exists()
- Parameters:
must_exist (
bool
) –type (
typing.Optional
[str
]) –
- clldutils.clilib.add_format(parser, default='pipe')[source]
Add a format option, to be used with
Table
.- Parameters:
default (
str
) –
- class clldutils.clilib.Table(args, *cols, **kw)[source]
CLI tools outputting tabular data can use a Table object (optionally together with a cli option as in
add_format()
) to easily create configurable formats of tables.Table is a context manager which will print the formatted data to stdout at exit.
def register(parser): add_format(parser, default='simple') def run(args): with Table(args, 'col1', 'col2') as t: t.append(['val1', 'val2'])
Note
With –format=tsv Table will output proper TSV, suitable for “piping” to CSV tools like the ones from csvkit.
- Parameters:
args (
argparse.Namespace
) –
- clldutils.clilib.add_csv_field_size_limit(parser, default=None)[source]
Command line tools reading CSV might run into problems with Python’s csv.field_size_limit Adding this option to the cli allows users to override the default setting.
Usage:
def register(parser): add_csv_field_size_limit(parser)