Table of Contents
Related Searches: Python argparse, Python arguments, Python optional arguments, Python positional arguments, python argumentparser, python argparse example, python argparse boolean, python script arguments, python argparse list
In this tutorial we will explore argparse module from Python programming language. I will share multiple examples with different scenarios to use python argparse to process command line arguments. Now these input command line arguments can be optional or in the for of array of any other format. So our code must handle these accordingly.
What is command line argument?
Before we go ahead you should be familiar with the concept of command line arguments. Let us take a very simple example which I am sure you must have used in your career while working on Linux:
[root@server scripts]# ls -ltr /var/log/
total 1628
-rw-r--r--. 1 root root 489 Nov 7 2019 grubby_prune_debug
-rw-------. 1 root root 12174 May 25 2020 yum.log-20200525
-rw-------. 1 root root 0 Jul 23 2020 spooler-20210319
-rw-------. 1 root root 194 Mar 19 14:39 maillog-20210319
-rw-------. 1 root root 7880 Mar 19 15:06 yum.log-20210319
-rw-------. 1 root root 165274 Mar 19 15:12 messages-20210319
-rw-------. 1 root root 13106 Mar 19 15:12 secure-20210319
-rw-------. 1 root root 2948 Mar 19 15:46 cron-20210319
...
Here we are using ls
command used to list files and directories. Along with the ls
command I have used some command line arguments i.e. -ltr
which can also be used separately or in different order ls -l -t -r /var/log
and you should still get the same output.
You may also notice that ls
command works just fine without these input arguments, which means that these are all optional arguments. We can add these arguments to further refine the command output.
Similarly when we write a python script, we may have a requirement to support command line arguments to collect different values. We will explore this further using different examples.
Overview on python argparse
Python's standard library module for interpreting command-line arguments, argparse
, supplies a host of features, making it easy to add argument handling to scripts in a fashion that is consistent with other tools. You can make arguments required or optional, have the user supply values for certain arguments, or define default values. argparse
creates usage text, which the user can read using the --help argument, and checks the user-supplied arguments for validity.
Using argparse
is a four-step process.
- Create a parser object.
- Add arguments your program accepts to the parser object.
- Tell the parser object to parse your script's argv (short for argument vector, the list of arguments that were supplied to the script on launch); it checks them for consistency and stores the values.
- Use the object returned from the parser object in your script to access the values supplied in the arguments.
The default syntax to use ArgumentParser
object from python argparse is:
argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True)
Example-1: Create help or usage section
In this example we will create a basic help or usage section using python argparse. By default add_help
is enabled with ArgumentParser
so you can just execute the following code which will add a help section with an optional argument of -h
or --help
:
#!/usr/bin/env python3 import argparse ## You could also use ## parser = argparse.ArgumentParser(add_help=True) parser = argparse.ArgumentParser() parser.parse_args()
Output from this script:
Example-2: Parse argument without value
In this example we will pass certain options to our script which do not expect any value. For example use -v
or --verbose
to enable verbose output or use -q or --quiet to suppress the output. Now these are optional arguments and do not require a value. The presence or absence of the option determines the appropriate Boolean in the parser.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('-q', '--quiet', action='store_true', dest='quiet', help='Suppress Output' ) parser.add_argument('-v', '--verbose', action='store_true', help='Verbose Output' ) args = parser.parse_args() print('Quiet mode is %r.' % args.quiet)
We have defined our action
variable as store_true
, which is the reason why the parser will not expect a value. You can read more about action in Example-10 of this article.
Most options do not need an action to be specified (the default is store
, which stores the value it receives). The specification of store_true
or store_false
is the most common way to indicate that an option is a flag and should not accept a value.
The dest
keyword argument determines how to look up the parsed value (in this case, True
or False
) on the object you get back when you call parse_args
. The string used here will be the attribute name on the object. In many cases, the dest
keyword argument is optional.
ArgumentParser
determines an intuitive name based on the name of the option itself. However, it is useful to explicitly provide this for readability and maintainability.
Output from this script with different optional arguments:
~]# python3 eg-2.py -h usage: eg-2.py [-h] [-q] [-v] optional arguments: -h, --help show this help message and exit -q, --quiet Suppress Output -v, --verbose Verbose Output ~]# python3 eg-2.py -v Quiet mode is False. ~]# python3 eg-2.py -q Quiet mode is True.
Example-3: Use different prefix for command line arguments
Normally in Linux and Uni we use single (-
) or double hyphen (--
) as the prefix for all the command line arguments. But for Windows we prefer forward slash (or simply slash) character (/
).
You can change which characters are used for prefixes by providing the prefix_chars
keyword argument to the ArgumentParser
constructor, as shown here:
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser(prefix_chars='/') parser.add_argument('/q', '//quiet', action='store_true', dest='quiet', help='Suppress Output' ) args = parser.parse_args() print('Quiet mode is %r.' % args.quiet)
In this example, we changed the prefix character to /
. Note that this also means that the argument itself (the one passed to add_argument
) must change accordingly. Calling this script is still straightforward. You simply must use /q
or //quiet
(rather than -q
or --quiet
).
Output from this script:
Example-4: Pass single value to python argument
We already defined an option flag which doesn't expect any value by using store_true
for action
keyword in Example-2 above. Here we have not defined any action
so by default it would expect a value for the input argument.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('-H', '--host', default='localhost', dest='host', help='Provide destination host. Defaults to localhost', type=str ) args = parser.parse_args() print(f'The host is "{args.host}"')
The script expects -H
or --host
argument with a single value which will be considered as destination host. We have defined a default value so that if we don't define a host then localhost will be considered as the default destination. Additionally we are also using type
keyword to convert the input argument value to string type.
Here we are executing our sample script with different values using -H
option:
Example-5: Pass multiple values in single argument
In the previous example we were passing single value to -H
input argument. Let's see, what would happen if I pass no value or more than one values to -H
:
~]# python3 eg-4.py -H usage: eg-4.py [-h] [-H HOST] eg-4.py: error: argument -H/--host: expected one argument ~]# python3 eg-4.py -H host1 host2 usage: eg-4.py [-h] [-H HOST] eg-4.py: error: unrecognized arguments: host2
So as expected, our parser argument fails to handle multiple values. You can set an option to accept an unbound number of arguments, or an exact number by using the nargs keyword argument to add_argument
.
In this example section we will cover following scenarios:
- Argument expects exactly 2 values
- Argument expects 1 or more values
- Argument expects 0 or more values
Scenario-1: Argument expects exactly 2 values
In this example we will write a script which expects an argument with exactly two values.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('--range', default=[1-100], dest='range', help='Define the range. Default is 1-100', type=int, nargs=2 ) args = parser.parse_args() print(f'The defined range is {args.range[0]}-{args.range[1]}')
This script expects --range
argument which should have exactly 2 values. The input values will be converted to integer type. Using nargs=2
we are restricting the number of values for --range
to exactly 2. Additionally we have also defined a default range value from 1-100
.
Let us try this script with different values:
~]# python3 eg-5-scenario-1.py -h usage: eg-5-scenario-1.py [-h] [--range RANGE RANGE] optional arguments: -h, --help show this help message and exit --range RANGE RANGE Define the range. Default is 1-100 ~]# python3 eg-5-scenario-1.py --range 5 100 The defined range is 5-100 ~]# python3 eg-5-scenario-1.py --range 5 usage: eg-5-scenario-1.py [-h] [--range RANGE RANGE] eg-5-scenario-1.py: error: argument --range: expected 2 arguments ~]# python3 eg-5-scenario-1.py --range 5 100 101 usage: eg-5-scenario-1.py [-h] [--range RANGE RANGE] eg-5-scenario-1.py: error: unrecognized arguments: 101
As expected when we try to give more than or less than 2 values to --range
argument, the script throws error because we have restricted the number of values to 2 using nargs
.
Scenario-2: Argument expects 1 or more values
You can use the +
value with nargs
which indicates that the option expects one or more values to be provided. Let us look at this example where we will perform addition using all the values provided to --num
argument.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('--num', dest='num', help='Define integers to perform addition', type=int, nargs='+' ) args = parser.parse_args() print('%s = %d' % ( ' + '.join([str(i) for i in args.num]), sum(args.num),))
Here we have defined nargs='+'
for --num
argument which means --num
expects one or more values.
Let us execute this script with one or more values for --num
argument:
~]# python3 eg-5-scenario-2.py --num 2 2 = 2 ~]# python3 eg-5-scenario-2.py --num 2 3 2 + 3 = 5 ~]# python3 eg-5-scenario-2.py --num 2 4 6 7 2 + 4 + 6 + 7 = 19 ~]# python3 eg-5-scenario-2.py --num usage: eg-5-scenario-2.py [-h] [--num NUM [NUM ...]] eg-5-scenario-2.py: error: argument --num: expected at least one argument ~]# python3 eg-5-scenario-2.py -h usage: eg-5-scenario-2.py [-h] [--num NUM [NUM ...]] optional arguments: -h, --help show this help message and exit --num NUM [NUM ...] Define integers to perform addition
Scenario-3: Argument expects 0 or more values
Similar to (+
) sign, you can use asterisk (*
) with nargs
to define zero or more values to a certain argument. We will update our script from Scenario-2 to use nargs='*'
for --num
argument and re-run the script:
~]# python3 eg-5-scenario-3.py --num = 0 ~]# python3 eg-5-scenario-3.py --num 1 2 3 1 + 2 + 3 = 6
So now our script doesn't fail when we don't provide any value to --num
argument.
Example-6: Pass mandatory argument using python argparse
In all our previous examples we were passing optional arguments to our python script. To pass a mandatory argument, you must use required keyword with True
flag i.e. required=True
.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('-s', '--sleep', required=True, default=20, dest='sleep', help='Provide sleep timer', type=int ) args = parser.parse_args() print('Provided sleep value is %r.' % args.sleep)
You may observe that when we execute this script and verify that -s
or --sleep
is required argument now.
~]# python3 eg-6.py
usage: eg-6.py [-h] -s SLEEP
eg-6.py: error: the following arguments are required: -s/--sleep
Although if you check the help section, -s
or --sleep
is shown under optional arguments section.
This is by design as parameters starting with -
or --
are usually considered optional. All other parameters are positional parameters and as such required by design (like positional function arguments). To overcome this you can parse the arguments and store into two different objects.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() # Create a new group to store required arguments requiredName = parser.add_argument_group('required named arguments') # Add required arguments to the parser requiredName.add_argument('-s', '--sleep', required=True, default=20, dest='sleep', metavar='TIME', help='Provide sleep timer', type=int ) # Add optional arguments to the parser parser.add_argument('-q', '--quiet', action='store_true', dest='quiet', help='Suppress Output' ) args = parser.parse_args() print('Provided sleep value is %r.' % args.sleep)
Output from this script:
Example-7: Pass multiple choices to python argument
Python ArgumentParser
adds the capability to specify that an option may only be one of an enumerated set of choices. These can be handled by passing a container object as the choices keyword argument to add_argument()
. When the command line is parsed, argument values will be checked, and an error message will be displayed if the argument was not one of the acceptable values:
This script expects any of the three values between blue
, black
and brown
for --color
argument. The default value would be blue
if --color
argument is not defined.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('--color', choices=('blue', 'black', 'brown'), dest='color', default='blue', help='Guess my lucky color' ) args = parser.parse_args() print('You have chosen %r.' % args.color)
Let us execute this script with different values for --color
argument:
~]# python3 eg-7.py -h usage: eg-7.py [-h] [--color {blue,black,brown}] optional arguments: -h, --help show this help message and exit --color {blue,black,brown} Guess my lucky color ~]# python3 eg-7.py You have chosen 'blue'. ~]# python3 eg-7.py --color red usage: eg-7.py [-h] [--color {blue,black,brown}] eg-7.py: error: argument --color: invalid choice: 'red' (choose from 'blue', 'black', 'brown')
Example-8: Pass positional arguments with python argparse
With python argparse
, you must declare your positional arguments explicitly. If you do not, the parser expects to have no arguments left over after it completes parsing, and it raises an error if arguments still remain.
How do we define optional and positional arguments?
The declaration for positional arguments is equivalent to the declaration for options, except that the leading hyphen is omitted.
When parse_args()
is called, optional arguments will be identified by the -
prefix, and the remaining arguments will be assumed to be positional.
For example, an optional argument could be created like:
>>> parser.add_argument('-f', '--foo')
while a positional argument could be created like:
>>> parser.add_argument('bar')
We will use the same code as we used in Example-5 to demonstrate nargs
keyword. This script will expect integers as positional arguments which can be one or more. We will perform a SUM operation on these provided integers. We are explicitly converting the provided values into integers using type=int
.
The code we used is mostly the same, except that the --num
argument has been replaced with num
, without the double-hyphen prefix.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('num', nargs='+', type=int, help='Provide integers to perform SUM' ) args = parser.parse_args() print('%s = %d' % (' + '.join([str(i) for i in args.num]), sum(args.num),))
You can see that there is a new section of positional arguments in the help section now:
We can now execute our script without num
argument:
~]# python3 eg-8.py 1 2 3 1 + 2 + 3 = 6
Example-9: Read a file as an input to python arguments
The Python argparse
module provides a special class that can be sent to the type keyword argument of add_argument
, which is argparse.FileType.
The argparse.FileType
class expects the arguments that would be sent to Python's open function, excluding the filename (which is what is being provided by the user invoking the program). If you are opening the file for reading, this may be nothing. open
defaults to opening files only for reading. However, any arguments after the initial positional argument to open can be provided to FileType
, and they will be passed on to open
.
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('--file', type=argparse.FileType('r'), dest='myfile', default='/tmp/file', help='The config file to use' ) args = parser.parse_args() print(args.myfile.read())
This would read from /tmp/file
by default, but allow you to specify a different file to read from using the --file
argument. Rather than providing these options as text and forcing you to open the file yourself, you will simply be provided with an open
file object:
~]# python3 eg-9.py
This is a test file
You may overwrite the default option by using --file
argument:
~]# python3 eg-9.py --file /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.43.31 server1 server1.example.com
Following is the help section:
~]# python3 eg-9.py -h usage: eg-9.py [-h] [--color MYFILE] optional arguments: -h, --help show this help message and exit --color MYFILE The config file to use
Example-10: Using “action” with ArgumentParser
ArgumentParser
objects associate command-line arguments with actions. These actions can do just about anything with the command-line arguments associated with them, though most actions simply add an attribute to the object returned by parse_args()
.
Any of six built-in actions can be triggered when an argument is encountered:
- store: Save the value, after optionally converting it to a different type. This is the default action taken if none is specified explicitly.
- store_const: Save a value defined as part of the argument specification, rather than a value that comes from the arguments being parsed. This is typically used to implement command-line flags that are not boolean values.
- store_true/store_false: Save the appropriate boolean value. These actions are used to implement Boolean switches.
- append: Save the value to a list. Multiple values are saved if the argument is repeated.
- append_const: Save a value defined in the argument specification to a list.
- version: Print the version details about the program and then exit.
In this example we have defined all the possible actions which can be used with ArgumentParser()
:
#!/usr/bin/env python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('-s', action='store', dest='simple_value', help='Store a simple value') parser.add_argument('-c', action='store_const', dest='constant_value', const='value-to-store', help='Store a constant value') parser.add_argument('-t', action='store_true', default=False, dest='boolean_t', help='Set a switch to true') parser.add_argument('-f', action='store_false', default=True, dest='boolean_f', help='Set a switch to false') parser.add_argument('-a', action='append', dest='collection', default=[], help='Add repeated values to a list') parser.add_argument('-A', action='append_const', dest='const_collection', const='value-1-to-append', default=[], help='Added different values to list') parser.add_argument('-B', action='append_const', dest='const_collection', const='value-2-to-append', help='Add different values to list') parser.add_argument('--version', action='version', version='%(prog)s 1.0') results = parser.parse_args() print('simple_value = {!r}'.format(results.simple_value)) print('constant_value = {!r}'.format(results.constant_value)) print('boolean_t = {!r}'.format(results.boolean_t)) print('boolean_f = {!r}'.format(results.boolean_f)) print('collection = {!r}'.format(results.collection)) print('const_collection = {!r}'.format(results.const_collection))
Following is our help
section:
'store' - This just stores the argument’s value. This is the default action. For example:
'store_const' - This stores the value specified by the const keyword argument.
'store_true' and 'store_false' - These are special cases of 'store_const' used for storing the values True and False respectively.
'append' - This stores a list, and appends each argument value to the list. This is useful to allow an option to be specified multiple times.
'append_const' - This stores a list, and appends the value specified by the const keyword argument to the list.
'version' - This expects a version= keyword argument in the add_argument()
call, and prints version information and exits when invoked
~]# python3 eg-10.py --version
eg-10.py 1.0
Summary
In this Python programming tutorial we learned about argparse module and it's usage to create help section. The argparse modules provide very good support for reading data from the command line for Python programs that need to do this. The argparse module supersedes optparse module.
The argparse module supports essentially all of optparse's features, and adds several additional ones, such as multiple arguments, better support for files, and more. Additionally, argparse's handling of positional arguments is more consistent with its handling of options, and results in more robust handling as well as a more useful help output.