Argparse: Default values not shown for subparsers - python

I have the problem that I am not seeing any default values for arguments when specifying them via add_argument for subparsers using the argparse Python package.
Some research said that you need non-empty help-parameters set for each add_argument step and you need ArgumentDefaultsHelpFormatter as formatter_class as described here:
Argparse: Way to include default values in '--help'?
That's not working for me, however. I suspect that somehow the subparser defaults are suppressed.
Here's an example:
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
parser = ArgumentParser(description="Sample script", formatter_class=ArgumentDefaultsHelpFormatter, version="sample version")
# Initialize Subparsers
subparsers = parser.add_subparsers(help="", dest="command")
# foo command
fooparser = subparsers.add_parser('foo', help='Do foo')
fooparser.add_argument('files', action='store', help='Foo file(s)' , nargs="+")
fooparser.add_argument("-5", "--Do5", type=int, required=False, dest="do5", help="Do 5 subprocedure.")
fooparser.add_argument("-n", "--topn", type=int, required=False, dest="topn", default=1, help="Show topn")
# bar command
barparser = subparsers.add_parser('bar', help='Do bar')
barparser.add_argument('files', action='store', help='Bar file(s)' , nargs="+")
barparser.add_argument("-mq", "--min-mq", type=int, required=False, default=2, dest="mq", help="Minimum MQ")
barparser.add_argument("-mi", "--min-identity", type=float, required=False, default=0.95, dest="identity", help="Minimum identity")
args = parser.parse_args()

Specify formatter_class when adding sub-parsers.
subparsers = parser.add_subparsers(help="", dest="command")
fooparser = subparsers.add_parser('foo', help='Do foo',
formatter_class=ArgumentDefaultsHelpFormatter)
...
barparser = subparsers.add_parser('bar', help='Do bar',
formatter_class=ArgumentDefaultsHelpFormatter)
...
Output of python argparse_test.py --help foo:
usage: argparse_test.py foo [-h] [-5 DO5] [-n TOPN] files [files ...]
positional arguments:
files Foo file(s)
optional arguments:
-h, --help show this help message and exit
-5 DO5, --Do5 DO5 Do 5 subprocedure. (default: None)
-n TOPN, --topn TOPN Show topn (default: 1)

Related

How to set a group optional which contains several required arguments?

I'm using the argparse module.
My script need four arguments: arg1, arg2, group_arg1, group_arg2. arg1 and arg2 are required. group_arg1 and group_arg2 are grouped and the group is optional.
My code:
parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('--arg1', type=str, required=True)
parser.add_argument('--arg2', type=str, required=True)
test_group = parser.add_argument_group(title='Grouped Arguments') # Need to be optional
test_group.add_argument('--group_arg1', type=str, required=True)
test_group.add_argument('--group_arg2', type=str, required=True)
How to set a group optional which contains several required arguments?
For example:
Users must pass in --arg1 xx --arg2 xx or --arg1 xx --arg2 xx --group_arg1 xx --group_arg2 xx
Case --arg1 xx --arg2 xx --group_arg1 xx is not allowed.
You could define a custom function to evaluate if the arguments are required instead of just setting the boolean yourself
import argparse
import sys
def need_optionals():
return bool(len(set(sys.argv).intersection(('--group_arg1', '--group_arg2'))))
parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('--arg1', type=str, required=True)
parser.add_argument('--arg2', type=str, required=True)
# Need to be optional
test_group = parser.add_argument_group(title='Grouped Arguments')
test_group.add_argument('--group_arg1', type=str, required=need_optionals())
test_group.add_argument('--group_arg2', type=str, required=need_optionals())
print(parser.parse_args())

saving arguments with ArgumentParser in a dictionary

i obtain different arguments from command lines:
def get_args():
parser = ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
return args
I would like to save all the argument obtained from get_args in a dictionary (to save then in a file .json or in a .txt).
argparse.ArgumentParser.parse_args returns an argparse.Namespace object, which is trivial to turn into a dict. Straight from the documentation:
This class is deliberately simple, just an object subclass with a
readable string representation. If you prefer to have dict-like view
of the attributes, you can use the standard Python idiom, vars():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}
Create a dictionary and add them by parser keyword.
neural_dict = {}
neural_dict['EPOCHS'] = args.epochs
neural_dict['DECAY_EPOCH'] = args.decay_epoch
.
.
.
To add to dictionary using a for loop:
neural_dict = {}
parser = argparse.ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
#chepner is right...use his method instead
neural_dict = vars(args)

How can i receive 1 argument with the python library parser and use just the argument?

I'm doing a command line application to verify if a website is active, and i want to receive one argument, but the parser needs receive an argument and a valor for this argument, So my question is: How can i use just 1 argument ?
This is my code:
if __name__=="__main__":
import requests
import datetime
from time import sleep
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('u', help="Unique verification")
parser.add_argument('c', help="Continuos verification")
parser.add_argument('s', help="Check and save to file")
parser.add_argument('d', help="Documentation")
args = parser.parse_args()
main(parser.parse_args)
My function main receives a char, how can i use a char via command line?
You are currently creating mandatory positional arguments, so that a call like
python3 verify.py foo bar baz bye
would result in
args.u == 'foo'
args.c == 'bar'
args.s == 'baz'
args.d == 'bye'
You want to define four options, using the store_true action so that providing the option will set a flag from its default False value to True.
parser = argparse.ArgumentParser()
parser.add_argument('-u', action='store_true', help="Unique verification")
parser.add_argument('-c', action='store_true', help="Continuos verification")
parser.add_argument('-s', action='store_true', help="Check and save to file")
parser.add_argument('-d', action='store_true', help="Documentation")
args = parser.parse_args()
Now a call like
python3 verify.py -u -s
would result in
args.u == True
args.c == False
args.s == True
args.d == False
If you want to further restrict the user to exactly one of the four options, use a mutual-exclusion group.
# Same as above, calling group.add_argument, not parser.add_argument
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-u', action='store_true', help="Unique verification")
group.add_argument('-c', action='store_true', help="Continuos verification")
group.add_argument('-s', action='store_true', help="Check and save to file")
group.add_argument('-d', action='store_true', help="Documentation")
args = parser.parse_args()

argparse: Conditional add_argument

I am just new with Python and I am trying out argparse. I want to add an argument if the first argument is equal to something.
import argparse
class ArgsParser :
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument('command')
args = parser.parse_args()
if args.command == 'a' :
parser.add_argument('-b', required=True)
args = parser.parse_args()
self.b = args.b
def main():
parser = ArgsParser();
print parser.b
if __name__ == '__main__':
main()
When I run the script using
prog.py a -b="abc"
It gives an error
prog.py: error: unrecognized arguments: -b=abc
But if I run the script using
prog.py a
The result would be
prog.py: error: argument -b is required
I think you can do this with subparsers:
>>> import argparse
>>> parse = argparse.ArgumentParser()
>>> subparsers = parse.add_subparsers()
>>> parse_a = subparsers.add_parser('a')
>>> parse_a.add_argument('-b', required=True)
_StoreAction(option_strings=['-b'], dest='b', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parse.parse_args(['a'])
usage: a [-h] -b B
a: error: argument -b is required

Python Argparse add_mutually_exclusive_group()- Need ether 2 args or just 1 args

I am using Python's 2.7 argparse. I need it to where the user can enter arguements (-a and -b) OR (-c). But but not (-a and -b) and (-c) together. If (-a and -b) are chosen by the user instead of -c, both of them are required. How could I do this?
group_key = member_add.add_mutually_exclusive_group(required=True)
group_key.add_argument('-a',
required=True)
group_key.add_argument('-b',
required=True)
group_key.add_argument('-c',
required=True)
The current implementation of add_mutually_exclusive_group() doesn't actually
create mutually exclusive groups. There is a open bug to address this behavior.
Having said that, you could achieve this using:
(a) subcommands
Example code :
# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='help for subcommand')
# create the parser for the "cmd_1" command
parser_a = subparsers.add_parser('cmd_1', help='help for cmd_1')
parser_a.add_argument('-a', type=str, help='help for a')
parser_a.add_argument('-b', type=str, help='help for b')
# create the parser for the "cmd_2" command
parser_b = subparsers.add_parser('cmd_2', help='help for cmd_2')
parser_b.add_argument('-c', type=str, help='help for c')
parser.parse_args()
(b) Small hack for the simple case like yours :
ap=argparse.ArgumentParser()
# 1st group
ap.add_argument("-a", dest="value_a", help="help for a", required=False)
ap.add_argument("-b", dest="value_b", help="help for b", required=False)
# 2nd group
ap.add_argument("-c", dest="value_c", help="help for b", required=False)
args = ap.parse_args()
if (args.value_a or args.value_b):
if (args.value_a or args.value_b) and args.value_c:
print "-a and -b|-c are mutually exclusive ..."
elif not (args.value_a and args.value_b):
print "both -a and -b are required."

Categories

Resources