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

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)
clldutils.clilib.add_random_seed(parser, default=None)[source]

Command line tools may want to fix Python’s random.seed to ensure reproducible results.

Usage:

def register(parser):
    add_random_seed(parser, default=1234)
Parameters:

default (typing.Optional[int]) –

clldutils.clilib.confirm(question, default=True)[source]

Ask a yes/no question interactively.

Parameters:

question (str) – The text of the question to ask.

Return type:

bool

Returns:

True if the answer was “yes”, False otherwise.