A Quick Guide to the Python argparse Library

I recently needed to handle some arguments for a command line Python program. I considered using the built in sys.argv approach, but decided that it would be better to experiment with the argparse library. Along the way I found a few useful hints and tricks that might prove useful to others.

First Things First

It seems that argparse is not available via Anaconda so use pip install argparse to install and import argparse to import.

To use argparse in your code there are basically three main commands you will use:

import argparse

# 1 - create our argument parser object
parser = argparse.ArgumentParser(...)
# 2 - add any arguments we want to process, 
# more on the parameters you will need later
parser.add_argument(...) 
# we will likely use add_argument() multiple times ...
# 3 - process our received arguments out into a useable form
arguments = parser.parse_args()

You get a few nice quality of life benefits from argparse almost for free. One of these is that you can easily add help instructions which will be called when you run python file.py -h. You do this by adding a description parameter to ArgumentParser() and a help parameter to add_argument(). Another thing you can do is validate inputs by specifying a type in add_argument() as shown below. Additionally handling multiple switches like -v and –verbose is easy in argparse.

How To Use add_argument

The core of using argparse is adding the arguments using add_argument(). The official documentation is verbose and a little hard to follow so I shall break down a few of my key findings here

you can have one variable which does not have a keyword and can take a variable number of arguments as desired. These arguments must be typed first in the argument list when invoking:

parser.add_argument(
    'paths',
    metavar='N', # this means the variable is positional
    type=str,  # specify our type
    nargs='*',  # ? is zero or one, * is zero or more, + is one or more
    help='File or folder paths.',
)

creating a simple flag variable can be done like this:

# note that we specify both '-v' and '--verbose'
parser.add_argument(
    '-v',
    '--verbose',
    action='store_true', # this converts to a flag
    help='Display intermediate steps in processing',
)

creating a variable which can take parameters can be achieved like this:

parser.add_argument(
    '-s',
    '--save',
    required = False, # allows for omission
    type = str,
    nargs='?', # allows zero or more parameters
    default = None, # defaults to None for zero parameters
    help='Save data to specified folder',
)

And for basic usage that is about it. These three constructions should let you get started. I have included some more reading below for more advanced functions but this is a good starting point.

Testing argparse

But how do we test a function which relies on arguments being passed in at runtime? The fgood news is that it is actually remarkably simple. First wrap your arg parse code in a function. Then pass that function the sys.argv arguments it relies on under the hood explicitly rather than allowing it to pick them up implicitly. This then allows you to test your function using pytest or your other prefered testing framework. To do this just pass known arguments to your argument parsing function and test its returns.

import argparse

def parse_arguments(args):
    parser = argparse.ArgumentParser(...)
    parser.add_argument(...)
    # ...Create your parser as you like...
    return parser.parse_args()

# omit the first sys.argv since that is the program file
parser = parse_arguments(sys.argv[1:])

# tests would be of the form
import pytest
class TestArgParser:
    def test_arparse_verbose(self, ):
        parser = parse_arguments(['-v'])
        assert parser.verbose is True

Other Reading

The official argparse documentation can be found here: https://docs.python.org/2.7/library/argparse.html

There are also a couple of good quick start guides that go into the subject in more detail than this article including dealing with mutually exclusive options and creating subparsers :

https://docs.python.org/3/howto/argparse.html#

https://towardsdatascience.com/a-simple-guide-to-command-line-arguments-with-argparse-6824c30ab1c3

Finally my testing approach was shamelessly stolen from stackoverflow

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.