Package: docopt-subcommands
docopt-subcommandsA simple implementation of subcommands for docopt.docopt-subcommandsallows you to create subcommand-based programs
usingdocopt. A subcommand-based program is
one in which the main program uses a "subcommand" argument to tell it what to
do.The classic example of such a program isgit. Thegitcommand with no arguments doesn't do much of anything. Instead, it's the first
argument togit- thesubcommand- that tells it what to actually do. For
example:git logwill give you the log for your repository. Likewise:git rebaseis the subcommand for rebasing.docopt-subcommandsis here to help you create similar kinds of command-line
tools withdocopt'.QuickstartThe basic idea behinddocopt-subcommandsis simple:You provide a separatehandler functionfor each subcommand.The docstring for each handler function defines the docopt definition for
that subcommand.You register your handler functions with the names of the subcommands which
will invoke them.You provide a program name and (optionally) a top-level documentation string.Thendocopt-subcommandsdoes the work of stitching everything together into a
subcommand-driven program. Here's how it looks (from the includedexampels/basic_example.py):# Basic, most common usage of docopt_subcommandsimportdocopt_subcommandsasdsc# 1. Use the `command` decorator to add subcommands functions.@dsc.command()deffoo_handler(precommand_args,args):"""usage: {program} foo <name>Apply foo to a name."""print("Foo,{}".format(args['<name>']))@dsc.command()defbar_handler(precommand,args):"""usage: {program} bar <name>Apply bar to a name."""print("Bar,{}".format(args['<name>']))# 2. Pass a program name and version string to `main` to run a program with the# subcommands you defined with the decorators above.dsc.main(program='docopt-subcommand-example')If you run this program at the command line you'll see that you have a nice,
subcommand-based CLI program:$pythonbasic_example.py
Usage:docopt-subcommand-example[options]<command>[<args>...]$pythonbasic_example.py-h
docopt-subcommand-example

Usage:docopt-subcommand-example[options]<command>[<args>...]Options:-h--helpShowthisscreen.

Availablecommands:barfoo

See'docopt-subcommand-example help <command>'forhelponspecificcommands.

$pythonbasic_example.pyfoo
usage:docopt-subcommand-examplefoo<name>

$pythonbasic_example.pyfoo-h
usage:docopt-subcommand-examplefoo<name>

Applyfootoaname.

$pythonbasic_example.pyfooBubba
Foo,BubbaFor more examples, see theexamplesdirectory.Common optionsMany subcommand-based programs have a set of options that are common to all commands. A common example is--verbosewhich causes the program to print more information not matter which command is executed. Withdocopt_subcommandsyou specify these common options in the top-level docstring like this::TOP_LEVEL_DOC = """{program}Usage: {program} [options]  [ ...]Options:
-h --help   Show this screen
--verbose   Use verbose outputAvailable commands:
{available_commands}
"""With this docstring, you can provide the--verboseflag for any subcommand. Critically,common options must be provided before the subcommand name.So ifbarwas a subcommand in your program, you would write::my_program --verbose barbut not::my_program bar --verbosedocopt_subcommandsparses the complete command line in two passes. The first pass parses it with the top-level
docstring while the second pass uses the docstring for the specific command and only parses the part of the command line
after the common options. It then provides both of the parsed dicts to the subcommand handler: the first argument to the
handler is the result of the first pass, and the second argument is the result of the second pass.With this system, you can then use a single set of code to do "common configuration" for you program. For example,
here's how a handler might look:.. code-block:: python@dsc.command()
def bar_handler(precommand_args, args):
"""usage: {program} barApply bar to a name.
  """
  handle_common_option(precommand_args)
  name = args['<name>']
  print('Bar {}'.format(name))Advanced usageFor most users the basic usage described in "Quickstart" should be all you need,
but some users will need more control ofdocopt_subcommands. Thedocopt_subcommands.main()that we used earlier is really just a convenience
layer on top of the real workhorse,docopt_subcommands.Subcommands. You can
instantiate this class directly, bypassingmain(), and interact with it as you
need before actually invoke command-line processing.For the most part, the arguments to theSubcommandsinitializer are very
similar to those tomain(). This reflects the fact thatmain()really just
instantiates aSubcommandsinstance (if you don't provide one), populates it
with commands, and calls it with the command line arguments. You can do all of
these steps yourself if you need to.As an example, here's what the basic example above looks like if you construct aSubcommandsinstance directly.:importdocopt_subcommandsasdscimportsyssc=dsc.Subcommands(program='docopt-subcommand-example')@sc.command('foo')deffoo_handler(args):"""usage: {program} {command} <name>Apply foo to a name."""print("Foo,{}".format(args['<name>']))@sc.command('bar')defbar_handler(args):"""usage: {program} {command} <name>Apply bar to a name."""print("Bar,{}".format(args['<name>']))sc(sys.argv[1:])As you can see, it's not substantially different from the basic example.main()primarily just adds a layer of convenience - mostly by choosing
reasonable default values for some things - that you lose with this approach.