how to make python argparse to accept not declared argument - python

I have a script that receives online arguments using argparse, like this:
parser = argparse.ArgumentParser()
parser.add_argument(
"--local", action="store_true", help=("Write outputs to local disk.")
)
parser.add_argument(
"--swe", action="store_true", help=("Indicates 'staging' environment.")
)
args = parser.parse_args()
I want argparse to handle undeclared arguments and just to add them to the arguments dictionary, but it raises an error when I try python runner.py --local true --swe true --undeclared_argument this_is_a_test:
runner.py: error: unrecognized arguments: --undeclared_argument this_is_a_test

Related

Positional argument for subparser raises the error: invalid choice

I am new to argsparse thus this might pretty sure be a newbie mistake so please bare with me. My code:
import argsparse
parent_parser = argparse.ArgumentParser(description='Argument Parser')
subparsers = parent_parser.add_subparsers(title="Sub-commands", description='Sub-commands Parser')
parser_create = subparsers.add_parser('run', parents=[parent_parser], add_help=False, help="run the program")
parser_create.add_argument('--program', metavar=('NAME'), required=True, type=str, help='name of the program')
This works perfectly fine when running parser.py run --program 'test' in the console:
args = parent_parser.parse_args(); print(args) outputs Namespace(program='test')
However, when I try to replace the optional argument with a positional one like:
parser_create.add_argument('program', metavar=('NAME'), type=str, help='name of the program')
And then run parser.py run 'test' in the console the following error is raised:
usage: parser.py run [-h] {run} ... NAME
parser.py run: error: invalid choice: 'test' (choose from 'run')
Adding the positional argument to a group results in the same error as above:
required = parser_create.add_argument_group('required positional argument')
required.add_argument('program', metavar=('NAME'), type=str, help='name of the program')
How can I pass positional arguments to the subparser formatted as run <program>?
I would appreciate any feedback. Thanks!
Thanks #PhilippSelenium for pointing out the link to the docs.
I solved this by removing parents=[parent_parser] from subparsers.add_parser()

How can I parse flags in command line argument?

I have to implement a --pos flag in Python and create a new condition if it exists, but argparse does not recognize it when I enter it in the command line argument.
parser = argparse.ArgumentParser()
parser.add_argument('lang', type=str, help='Language')
parser.add_argument('mode', help='the mode you want to output the results with')
parser.add_argument('flag', help='the flag that triggers pos-tags')
args = parser.parse_args()
So when I run the command:
python3 pi.py en lemma --pos
I get the following error message:
error: unrecognized arguments: --pos
Is there a way to catch that flag as a third argument?
In your code you are defining a "positional argument" which is not what you want. If you want to implement a flag (true/false) --pos just do that.
...
parser.add_argument('--pos', action='store_true', help='the flag that triggers pos-tags')
args = parser.parse_args()
if args.pos:
...
and call it as
python3 pi.py en lemma --pos

combining argsparse and sys.args in Python3

I'm trying to write a command line tool for Python that I can run like this..
orgtoanki 'b' 'aj.org' --delimiter="~" --fields="front,back"
Here's the script:
#!/usr/bin/env python3
import sys
import argparse
from orgtoanki.api import create_package
parser = argparse.ArgumentParser()
parser.add_argument('--fields', '-f', help="fields, separated by commas", type=str, default='front,back')
parser.add_argument('--delimiter', '-d', help="delimiter", type= str, default='*')
args = parser.parse_args()
name=sys.argv[1]
org_src=sys.argv[2]
create_package(name, org_src, args.fields, agrs.delimiter)
When I run it, I get the following error:
usage: orgtoanki [-h] [--fields FIELDS] [--delimiter DELIMITER]
orgtoanki: error: unrecognized arguments: b aj.org
Why aren't 'b' and 'ab.org' being interpreted as sys.argv[1] and sys.argv[2], respectively?
And will the default work as I expect it to, if fields and delimiter aren't supplied to the command line?
The error here is caused by argparse parser which fails to apprehend the 'b' 'aj.org' part of the command, and your code never reaches the lines with sys.argv. Try adding those arguments to the argparse and avoid using both argparse and sys.argv simultaneously:
parser = argparse.ArgumentParser()
# these two lines
parser.add_argument('name', type=str)
parser.add_argument('org_src', type=str)
parser.add_argument('--fields', '-f', help="fields, separated by commas",
type=str, default='front,back')
parser.add_argument('--delimiter', '-d', help="delimiter",
type= str, default='*')
args = parser.parse_args()
You then can access their values at args.name and args.org_src respectively.
The default input to parser.parse_args is sys.argv[1:].
usage: orgtoanki [-h] [--fields FIELDS] [--delimiter DELIMITER]
orgtoanki: error: unrecognized arguments: b aj.org
The error message was printed by argparse, followed by an sys exit.
The message means that it found strings in sys.argv[1:] that it wasn't programmed to recognize. You only told it about the '--fields' and '--delimiter' flags.
You could add two positional fields as suggested by others.
Or you could use
[args, extras] = parser.parse_known_args()
name, org_src = extras
extras should then be a list ['b', 'aj.org'], the unrecognized arguments, which you could assign to your 2 variables.
Parsers don't (usually) consume and modify sys.argv. So several parsers (argparse or other) can read the same sys.argv. But for that to work they have to be forgiving about strings they don't need or recognize.

Allow unknown arguments using argparse

I have a python script that requires the user to enter two arguments to run it, the arguments could be named anything.
I have also used argparse to allow the users to use a switch '-h' to get instructions of what is required to run the script.
The problem is that now I have used argparse I am getting an error when I pass my two randomly named arguments with the script.
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help',
help='To run this script please provide two arguments')
parser.parse_args()
currently when I run python test.py arg1 arg2 the error is
error: unrecognized arguments: arg1 arg2
I would like the code to allow the user to run test.py with a -h if required to see the instructions but also allow them to run the script with any two arguments as well.
Resolution with help tag to provide the user with context regarding the arguments required.
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help', help='To run this script please provide two arguments: first argument should be your scorm package name, second argument should be your html file name. Note: Any current zipped folder in the run directory with the same scorm package name will be overwritten.')
parser.add_argument('package_name', action="store", help='Please provide your scorm package name as the first argument')
parser.add_argument('html_file_name', action="store", help='Please provide your html file name as the second argument')
parser.parse_args()
Try the following code :-
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help',
help='To run this script please provide two arguments')
parser.add_argument('arg1')
parser.add_argument('arg2')
args, unknown = parser.parse_known_args()
All your unknown arguments will be parsed in unknown and all known in args.
import argparse
parser = argparse.ArgumentParser(description='sample')
# Add mandatory arguments
parser.add_argument('arg1', action="store")
parser.add_argument('arg2', action="store")
# Parse the arguments
args = parser.parse_args()
# sample usage of args
print (float(args.arg1) + float(args.arg2))
You need to add those arguments to the parser:
parser.add_argument("--arg1", "-a1", dest='arg1', type=str)
parser.add_argument("--arg2","-a2", dest='arg2', type=str)
If those arguments don't have the param required=true, you will be able to call the program without this arguments, so you can run the program with only the -h flag. To run the program with the arguments:
python test.py --arg1 "Argument" --arg2 "Argument"
Then, to have the arguments in variables you have to read them:
args = parser.parse_args()
argument1=args.arg1
argument2=args.arg2

Python Argument Parser - the following arguments are reqired --name

When I run the following code:
def read_args():
parser = default_parser()
parser.add_argument('--tensorboard-dir', type=str, default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000, help="Use N training examples.")
return parser.parse_args()
def main():
flags = readargs()
I have the following error output:
The following arguments are required: --name
However when I add the --name argument:
def read_args():
parser = default_parser()
parser.add_argument('--name', type=str, default='cifar10test')
parser.add_argument('--tensorboard-dir', type=str, default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000, help="Use N training examples.")
return parser.parse_args()
def main():
flags = readargs()
is also creating problem.
Any ideas?
It appears that default_parser contains a --name argument which is required. What you're doing in your second example is defining the argument twice - once in default_parser and once in your program. Instead, you should be passing a --name argument when calling your program from the command line.
Example:
python cifar.py -N=1200 --tensorboard-dir=file.txt --name=cool_name
Alternatively, you could remove default_parser and construct your own ArgumentParser:
`parser = argparse.ArgumentParser()`
Full working demo:
import argparse
def read_args():
parser = argparse.ArgumentParser()
parser.add_argument('--tensorboard-dir', type=str,
default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000,
help="Use N training examples.")
return parser.parse_args()
def main():
flags = vars(read_args())
# You can access your args as a dictionary
for key in flags:
print("{} is {}".format(key, flags[key]))
main()
The parser returns a Namespace object, but we can access its (much simpler) internal dictionary using vars(Namespace). You can then get your arguments by accessing the dictionary, for example, flags['N']. Note that tensorboard-dir becomes tensorboard_dir inside your python program to avoid issues with the subtraction operator.
Call it from the command line (I'm using Bash):
python cifar.py -N=1200 --tensorboard-dir=file.txt
Output:
tensorboard_dir is file.txt
N is 1200

Categories

Resources