Python Argparse Conditionally Required Arguments

Python Argparse - conditionally required arguments based on the value of another argument

I think you can use two parsers to do that:

import argparse

if __name__ == '__main__':
command_parser = argparse.ArgumentParser()
command_parser.add_argument('-c', '--command', required=True,
help='provide a valid command: start, stop, restart, or status')

if command_parser.parse_known_args()[0].command.lower().startswith('start'):
option_parser = argparse.ArgumentParser()
option_parser.add_argument('-d', '--download', required=True, help='set account download folder')
option_parser.add_argument('-j', '--input', required=True, help='set input json file')
option_parser.parse_known_args()

or you can use a subparser, which is probably better in your case:

import argparse

if __name__ == '__main__':
command_parser = argparse.ArgumentParser()

subparsers = command_parser.add_subparsers(help='Choose a command')

start_parser = subparsers.add_parser('start', help='"start" help')
start_parser.add_argument('-d', '--download', required=True, help='set account download folder')
start_parser.add_argument('-j', '--input', required=True, help='set input json file')
start_parser.set_defaults(action=lambda: 'start')

stop_parser = subparsers.add_parser('stop', help='"stop" help')
stop_parser.set_defaults(action=lambda: 'stop')

command_parser.parse_args()

in this case command line syntax will be bit different:

python3 test.py start -d /mydownloadfolder/ -j /myconfig.json

python3 test.py stop

Python argparse - Add mandatory arguments with condition

You can check the condition and then check if the other arguments are both provided.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-n','--name', required=True)
parser.add_argument("-sd", "--start_date", dest="start_date",
help="Date in the format yyyy-mm-dd")
parser.add_argument("-ed", "--end_date", dest="end_date",
help="Date in the format yyyy-mm-dd")

args = parser.parse_args()

if args.name == "test1":
if args.start_date is None or args.end_date is None:
parser.error('Requiring start and end date if test1 is provided')

Conditional command line arguments in Python using argparse

You could use parser.error:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--action', choices=['upload', 'dump'], default='dump')
parser.add_argument('--dump-format')
args = parser.parse_args()
if args.action != 'dump' and args.dump_format:
parser.error('--dump-format can only be set when --action=dump.')

Argparse: Required argument 'y' if 'x' is present

No, there isn't any option in argparse to make mutually inclusive sets of options.

The simplest way to deal with this would be:

if args.prox and (args.lport is None or args.rport is None):
parser.error("--prox requires --lport and --rport.")

Actually there's already an open PR with an enhancement proposal :
https://github.com/python/cpython/issues/55797

Python argparse conditional requirements

A subparser (as suggested in comments) might work.

Another alternative (since mutually_exclusive_group can't quite do this) is just to code it manually, as it were:

import argparse

def main():
parser = argparse.ArgumentParser()

parser.add_argument('-2', dest='two', action='store_true')
parser.add_argument('-3', dest='three')
parser.add_argument('-4', dest='four')
parser.add_argument('-5', dest='five')

args = parser.parse_args()

if not args.two:
if args.three is None or args.four is None:
parser.error('without -2, *both* -3 <a> *and* -4 <b> are required')

print args
return 0

Adding a little driver to this:

import sys
sys.exit(main())

and run with your examples, it seems to do the right thing; here are two runs:

$ python mxgroup.py -2; echo $?
Namespace(five=None, four=None, three=None, two=True)
0
$ python mxgroup.py -3 a; echo $?
usage: mxgroup.py [-h] [-2] [-3 THREE] [-4 FOUR] [-5 FIVE]
mxgroup.py: error: without -2, *both* -3 <a> *and* -4 <b> are required
2
$

Argument Parser Python conditional requirement

You could use add_mutually_exclusive_group method like so:

from argparse import ArgumentParser

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--show', help='...', action='store_true')
group.add_argument('--list', help='...', action='store_true')
group.add_argument('--add', type=str, help='...')

parser.add_argument("--number", type=int, required=False)
parser.add_argument("--email", type=str, required=False)

args = parser.parse_args()

if args.add:
# proceed with args.number and args.email
else:
# ignore args.number and args.email...

Output:

$ python test.py
usage: test.py [-h] (--show | --list | --add ADD) [--number NUMBER]
[--email EMAIL]
test.py: error: one of the arguments --show --list --add is required


Related Topics



Leave a reply



Submit