Jones Doe
Jones Doe

Reputation: 51

Make a command-line-based application with python argparse only

I would want to make a command-line-based application using python and argparse library. But I am having some challenges with this library, This is the command looks like (the usage):

prog (foo|bar) [-v] (-h "key:value")* [-d inline-data] [-f file] URL

This is the prog help output:

> prog help
prog is a simple application
Usage:
prog command [arguments]
The commands are:
foo executes FOO
bar executes BAR
help prints this screen.
Use "prog help [command]" for more information about a command.

My challenge is in this part. I want to give separate help description when we execute the following commands:
prog help foo
prog help bar

import argparse
parser = argparse.ArgumentParser(prog='prog.py',description='some help', add_help=False)
#I turned off the default help, and defined -h separately.
parser.add_argument('-h', '--header', metavar='', help='headerHelpString')
subparsers = parser.add_subparsers(help='help sub-command')
subparserHelp = subparsers.add_parser('help', help='some help')
subparserFooBar = subparserHelp.add_argument('method', choices=['foo', 'bar'])
group = parser.add_mutually_exclusive_group()
group.add_argument('-q', '--quiet', action='store_true', help='print quiet')
group.add_argument('-v', '--verbose', action='store_true', help='print verbose')
args = parser.parse_args()

Upvotes: 2

Views: 198

Answers (1)

hpaulj
hpaulj

Reputation: 231510

Without arguments, I get an error - it requires the subparsers command, 'help'. As defined there are a couple of flagged arguments for the toplevel. Arguments for the subparser are not displayed in the usage (or full help if it was enabled).

1327:~/mypy$ python stack46982125.py 
usage: prog.py [-h] [-q | -v] {help} ...
prog.py: error: too few arguments

In Py3 subparsers are 'optional', showing what would be set:

1328:~/mypy$ python3 stack46982125.py 
Namespace(header=None, quiet=False, verbose=False)

With the 'help' subparser, usage includes '[-h]', but this is the default help. The subparsers doesn't inherit the add_help parameter; you have to set that explicitly.

1328:~/mypy$ python3 stack46982125.py help
usage: prog.py help [-h] {foo,bar}
prog.py help: error: the following arguments are required: method

Taking advantage of that -h, I get the same usage with a fuller help.

1329:~/mypy$ python3 stack46982125.py help -h
usage: prog.py help [-h] {foo,bar}

positional arguments:
  {foo,bar}

optional arguments:
  -h, --help  show this help message and exit

And if I also define the required 'foo/bar' it parses fine.

1329:~/mypy$ python3 stack46982125.py help foo
Namespace(header=None, method='foo', quiet=False, verbose=False)

If I add

parser.print_help()
subparserHelp.print_help()

I get the added output:

usage: prog.py [-h] [-q | -v] {help} ...

some help

positional arguments:
  {help}          help sub-command
    help          some help

optional arguments:
  -h , --header   headerHelpString
  -q, --quiet     print quiet
  -v, --verbose   print verbose
usage: prog.py help [-h] {foo,bar}

positional arguments:
  {foo,bar}

optional arguments:
  -h, --help  show this help message and exit

If I add a dest parameter

subparsers = parser.add_subparsers(dest='cmd', help='help sub-command')

And make the prints conditional

if args.cmd == 'help':
    parser.print_help()
    subparserHelp.print_help()

No display of help (in py3) or error as above (py2)

1340:~/mypy$ python3 stack46982125.py
Namespace(cmd=None, header=None, quiet=False, verbose=False)

display of helps:

1341:~/mypy$ python3 stack46982125.py help foo
Namespace(cmd='help', header=None, method='foo', quiet=False, verbose=False)
....

If you turn off the -h help, then you have to somehow capture the 'help' string, and act on it with your own help or the print_help method. You can also define another flagged argument and give it an action='help' parameter.

Do you really need to turn turn off the default add_help. Isn't it simpler to use the default help approach? It's probably more familiar to your users.

Upvotes: 1

Related Questions