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

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())

Related

passing a dict with arguments to argparse

I am using a codebase that expects a large set of argument via command line using argparse library and I neet to call that code inside a loop and inject the arguments via dictionary and not via command line without changing that codebase, I call the code as follow:
parser = argparse.ArgumentParser('Training', parents=[get_args_parser()])
args = parser.parse_args()
main(args)
Where get_args_parser() is a large list of arguments and defaults such as :
def get_args_parser():
parser = argparse.ArgumentParser('Set transformer detector', add_help=False)
parser.add_argument('--lr', default=1e-4, type=float)
parser.add_argument('--lr_backbone', default=1e-5, type=float)
parser.add_argument('--batch_size', default=2, type=int)
parser.add_argument('--weight_decay', default=1e-4, type=float)
parser.add_argument('--epochs', default=300, type=int)
parser.add_argument('--lr_drop', default=200, type=int)
...
If i need to pass a dictionary , as arguments , like:
argdict = {'lr_drop':20,'batch_size':5}
How can I do it?
you should use like this:
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dict", required=True, help="Your dict as string", default="{}")
args = vars(ap.parse_args())
argdict = eval(args["dict"])
print(argdict)
# or you cam print some dict specific var
print(argdict["name"]) #Jasar
the you can call your file like it:
python3 file.py -d '{"name":"Jasar"}'
using some clues by #Jaser and #chepner , what i did is as follow:
args_to_argdict = {'a':1 , 'b':49 ,'c': 'text' }
parser = argparse.ArgumentParser(parents=[get_args_parser()])
args = parser.parse_args()
arg_dict = vars(args)
for key,value in args_to_argdict.items():
arg_dict[key]= value
so that the args value change , then i run the main :
main(args)
with the modified 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()

How to declare two different type variables through argpars

Argps approach need to accept two different types of variables, in this case only the array of string is accepting values and the int variable do not. how do i solve this? or is this the best approach to the case? I´m very new whit python thanks to all
python code:
def read_cmdline_args():
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--search_by_name", help="Search by name",
type=str, nargs='+')
args = parser.parse_args()
return args
cmdline_args = read_cmdline_args()
uSerach_by_name = cmdline_args.serach_by_name
session.serach_by_name(tags=uSerach_by_name, amount=uSerach_by_name)
Original method:
session.serach_by_name(["peter"], amount=2)
command line:
py quickstart.py --l peter john 2 (the value 2 which is amount is not being accepted )
Do you want to pass list of words and some number? Simply add another argument:
def read_cmdline_args():
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--search_by_name", type=str, nargs='+', help="Search by name")
# added argument
parser.add_argument("-a", "--amount", type=int, default=0, help="Some amount")
return parser.parse_args()
Now you can run the script like this:
py quickstart.py -s peter john -a 2
Parsed arguments are:
Namespace(amount=2, search_by_name=['peter', 'john'])

Argparse: Default values not shown for subparsers

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)

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