Cyberwiz
Cyberwiz

Reputation: 11426

Python argparse: Is there a way to print help for only a specific parameter?

I have a long list of parameters, so the output from mycommand --help is getting very big. I would like to provide my users a way to get the help text for only a specific parameter.

Something like this (doesn't work, shows the whole help text)

mycommand --help --parameter-of-interest

I don't want to split everything into subparsers if at all avoidable.

Upvotes: 2

Views: 1881

Answers (2)

Alex
Alex

Reputation: 7075

You can create your own actions to achieve this. Both of these will iterate the optional arguments and suppress any that are not found in sys.argv. I'd recommend the explain action as this doesn't mess with the -h/--help flag.

Explain Action

This creates an action ExplainParamsAction with the corresponding -e/--explain options that filters the help text for just specified parameters.

import sys
import argparse

class ExplainParamsAction(argparse.Action):
    def __init__(
        self,
        option_strings,
        dest=argparse.SUPPRESS,
        default=argparse.SUPPRESS,
        **kwargs
    ):
        super().__init__(option_strings, dest, default=default, nargs=0, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        opts = parser._option_string_actions
        for arg in opts:
            if arg not in sys.argv:
                setattr(opts[arg], "help", argparse.SUPPRESS)
        parser.print_help()
        parser.exit()

parser = argparse.ArgumentParser()
parser.add_argument(
    "-e",
    "--explain",
    action=ExplainParamsAction,
    help="Show help message for only specified parameters and exit",
)
parser.add_argument("--url", help="URL to the resource")
parser.add_argument("--port", help="Port to the resource")
parser.add_argument("--timeout", help="Connection timeout")
args = parser.parse_args()

Override the Help Action

Alternatively you can override the help action that you supply to your parser. To use with an argparse.ArgumentParser you need to turn off the default helper and provide your own.

import sys
import argparse

class _CustomHelpAction(argparse._HelpAction):
    def __call__(self, parser, namespace, values, option_string=None):
        args = sys.argv[1:]
        opts = parser._option_string_actions
        # Check is needed for just -h/--help to work
        if len(args) > 1:
            for arg in opts:
                if arg not in args:
                    setattr(opts[arg], "help", argparse.SUPPRESS)
        super().__call__(parser, namespace, values, option_string)


# Init parser with help turned off
parser = argparse.ArgumentParser(add_help=False)

# Register your help action and manually add the `-h/--help` option
parser.register("action", "help", _CustomHelpAction)
parser.add_argument("-h", "--help", action="help", help="show this help message and exit")

# Add remaining arguments
parser.add_argument("--url", help="URL to the resource")
parser.add_argument("--port", help="Port to the resource")
parser.add_argument("--timeout", help="Connection timeout")
args = parser.parse_args()

Example usage:

All help:

python3 script.py --help
usage: script.py [-h] [--url URL] [--port PORT] [--timeout TIMEOUT]

optional arguments:
  -h, --help
  --url URL          URL to the resource
  --port PORT        Port to the resource
  --timeout TIMEOUT  Connection timeout

Specific parameters:

~ python3 script.py -h --url --timeout
usage: script.py [--url URL] [--timeout TIMEOUT]

optional arguments:
  --url URL          URL to the resource
  --timeout TIMEOUT  Connection timeout
~ python3 script.py -h --timeout --port
usage: script.py [--timeout TIMEOUT] [--port PORT]

optional arguments:
  --port PORT        Port to the resource
  --timeout TIMEOUT  Connection timeout

This naively assumes that you are only using sys.argv, I'm not really sure what would need to be done if it weren't.

Upvotes: 2

Kilian
Kilian

Reputation: 601

This has been discussed here: Customize argparse help message

In essence, you can overwrite the help by adding --help as argument.

Edit: the custom help could be pointing to a syntax for getting help on a specific parameter like -s parameter_you_wish_help_about.

Edit 2: Haven't tested it, but something along this lines.

parser.add_argument('-s',action='store',dest='para', type=str, help='Get Help on specific parameter')
parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, help='Use -s to get help on specific parameter')

help_dict={}
help_dict['para_1']='Help on para_1'
print (help_dict[args.para])

Upvotes: 1

Related Questions