Pass arguments via file and via command line [duplicate] - python

I want to launch my script like this:
python3 main.py #params.conf 1 2
where params.conf is a file and 1, 2 are string arguments.
I know how to parse file alone:
argparser = ArgumentParser()
argparser.add_argument('arg1', help='heeelp')
...
args = argparser.parse_args()
But how to parse following arguments?

An argument prefixed with # is treated as if its contents were in the command line directly, one argument per line. So if the contents of params.confis
2
3
And you define a parser like
import argparse
p = argparse.ArgumentParser(fromfile_prefix_chars='#')
p.add_argument("a")
p.add_argument("b")
p.add_argument("c")
p.add_argument("d")
args = p.parse_args()
and you call your script as
script.py 1 #params.conf 4
then your arguments a through d will be set to 1 through 4, respectively.

You just add more argparser.add_argument calls.
Like this:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg1', type=str)
parser.add_argument('arg2', type=str)
parser.add_argument('arg3', type=str)
args = parser.parse_args()
print(args) # arguments are parsed

Related

python get changed (non-default) cli arguments?

Given an argument parser with n arguments, where I change the default value of only a small subset every run from the command line, is there a clean way of extracting a dict/namespace of all the non-default k,v arguments?
parser = argparse.ArgumentParser()
parser.add_argument("--a",type=str,default='a')
parser.add_argument("--b",type=str,default='b')
parser.add_argument("--c",type=str,default='c')
parser.add_argument("--d",type=str,default='d')
And
python run.py --a "e"
I would like to have
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--a",type=str,default='a')
parser.add_argument("--b",type=str,default='b')
parser.add_argument("--c",type=str,default='c')
parser.add_argument("--d",type=str,default='d')
non_default = parse_non_default(parser) # non_default = {'a':'e'}
You could lookup the parser and compare which values differenciate:
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--a", type=str, default='a')
parser.add_argument("--b", type=str, default='b')
parser.add_argument("--c", type=str, default='c')
parser.add_argument("--d", type=str, default='d')
parser.add_argument("--n", type=int, default=999)
args = parser.parse_args(['--a', 'e']) # Test CLI arguments!
non_default = {
opt.dest: getattr(args, opt.dest)
for opt in parser._option_string_actions.values()
if hasattr(args, opt.dest) and opt.default != getattr(args, opt.dest)
}
print(non_default)
main()
Out:
{'a': 'e'}

argparse - how to pass argument from args into function?

import argparse
from queries import most_common_cities
parser = argparse.ArgumentParser(description='A script that does operations with database data and returns values')
parser.add_argument('-c', '--most_common_cities',
nargs=1,
type=positive_int,
help='Specify how many common cities.')
args = parser.parse_args()
if args.most_common_cities:
result = most_common_cities(n) # "n" should be an arg passed by user
print(result)
How could I pass arguments from CLI to my function arg?
When someone use command:
python argp.py --most_common_cities 5
It should return 5 most common cities.
Remove nargs=1, then args.most_common_cities will be the actual value passed in.
nargs=1 wraps it in a list.
parser.add_argument('-c', '--most_common_cities',
type=int,
help='Specify how many common cities.')
args = parser.parse_args(['-c', '5'])
n = args.most_common_cities
print(n)
print(type(n))
# 5
# <class 'int'>
I started your script with following command:
python3 test.py --most_common_cities 5
You can access the arguments with:
import argparse
parser = argparse.ArgumentParser(description='A script that does operations with database data and returns values')
parser.add_argument('-c', '--most_common_cities',
nargs=1,
type=int,
help='Specify how many common cities.')
args = parser.parse_args()
arguments = vars(parser.parse_args())
print(arguments) #{'most_common_cities': [5]}
#then you can access the value with:
arguments['most_common_cities']

Python argparse; if argument 1 not present, how to continue and set required next arguments

I have 3 arguments in my python script. Two are required for running the script and argument 1 shows only a list of options.
I want that if argument 1 is set, that argument 2 and 3 are not required anymore, and if argument 1 is not used, that argument 2 and 3 are required.
The arguments are as follows:
parser = argparse.ArgumentParser()
parser.add_argument("--1", help="list of options", action="store_true", default=False)
parser.add_argument("--2", help="level", required=True)
parser.add_argument("--3", help="folder", required=True)
args = parser.parse_args()
I tried it with the following command:
parser = argparse.ArgumentParser()
parser.add_argument("--1", help="list of options", action="store_true", default=False)
parser.add_argument("--2", help="level)
parser.add_argument("--3", help="folder")
args = parser.parse_args()
if args.1:
print('list of options')
sys.exit()
if not args.1:
parser = argparse.ArgumentParser()
parser.add_argument("--1", help="list of options", action="store_true", default=False)
parser.add_argument("--2", help="level", required=True)
parser.add_argument("--3", help="folder", required=True)
But the problem than is that if the user only set option 2 (or only option 3), that the script continues, instead of having both options 2 and 3 required.
Is it possible in Python to first test for option 1 and, if this option is not set, continue to test for option 2 and 3, and set these two as required?

Argparse arguments from file and string CLI arguments both

I want to launch my script like this:
python3 main.py #params.conf 1 2
where params.conf is a file and 1, 2 are string arguments.
I know how to parse file alone:
argparser = ArgumentParser()
argparser.add_argument('arg1', help='heeelp')
...
args = argparser.parse_args()
But how to parse following arguments?
An argument prefixed with # is treated as if its contents were in the command line directly, one argument per line. So if the contents of params.confis
2
3
And you define a parser like
import argparse
p = argparse.ArgumentParser(fromfile_prefix_chars='#')
p.add_argument("a")
p.add_argument("b")
p.add_argument("c")
p.add_argument("d")
args = p.parse_args()
and you call your script as
script.py 1 #params.conf 4
then your arguments a through d will be set to 1 through 4, respectively.
You just add more argparser.add_argument calls.
Like this:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg1', type=str)
parser.add_argument('arg2', type=str)
parser.add_argument('arg3', type=str)
args = parser.parse_args()
print(args) # arguments are parsed

python argparse doesn't take string option start with "--"

I simplifying my problem here. I need to do this:
python test.py --arg1 '--no-route53'
I added the parser like this:
parser.add_argument("--arg1", nargs="?", type=str, help="option")
args = parser.parse_args()
I wanted to get the '--no-route53' as a whole string and use it later in my script. But I keep getting this error:
test.py: error: unrecognized arguments: --no-route53
How can I work around it?
UPDATE1: if i give extra space after '--no-route53', like this and it worked:
python test.py --arg1 '--no-route53 '
I had the exact same issue a while ago. I ended up pre-parsing the sys.argvlist:
def bug_workaround(argv):
# arg needs to be prepended by space in order to not be interpreted as
# an option
add_space = False
args = []
for arg in argv[1:]: # Skip argv[0] as that should not be passed to parse_args
if add_space:
arg = " " + arg
add_space = True if arg == "--args" else False
args.append(arg)
return args
parser = argparse.ArgumentParser(description='My progrm.')
.
.
.
parser.add_argument('--args', type=str,
help='Extra args (in "quotes")')
args = parser.parse_args(bug_workaround(sys.argv))
# Prune added whitespace (for bug workaround)
if args.args:
args.args = args.args[1:]

Categories