Command-line or console applications are programs that are designed to be used via a text only interface such as the terminal. Command-line programs accept instructions or commands from their users in the form of flags or switches. Popular command-line applications include:
There are a number of Python modules designed for developing command-line interfaces. This post will focus on argparse
, the module that comes standard with Python.
Argparse
Argparse allows you to make user-friendly interfaces and add arguments to your command-line applications easily. The benefit of using a module like argparse is that it allows parsing and validation of user input without having to write lots of code. argparse
can also display appropriate messages when users enter incorrect input right out of the box.
In this article, I will introduce the most common argparse
features and show you how to build a simple calendar application.
Getting Started
The first thing to do is to import argparse
and create an ArgumentParser
object.
import argparse parser = argparse.ArgumentParser() parser.parse_args()
The code we just wrote doesn’t do much, except initialise the parser
object.
parser.parse_args()
returns a Namespace object that contains key-value pairs of arguments and their values. parse_args requires a list of strings as it’s input and it takes it’s input from sys.argv by default.
Running the script with the --help
option gives us the following output:
terra@shadow:/tmp$ python argparse_script.py --help usage: argparse_script.py [-h] optional arguments: -h, --help show this help message and exit
argparse
automatically adds a help flag or option to all instances of ArgumentParser()
. As you can see, from writing only three lines of code, we now have very basic usage documentation that tells us the name of the script and what optional arguments are supported. Let’s add more to the usage documentation.
import argparse parser = argparse.ArgumentParser() parser.prog = "Commandline Calendar" parser.description = "A simple utility to display a calendar." parser.epilog = "Full documentation available at http:www.example.com/"
That gives the script a Program name, and a description:
terra@shadow:/tmp$ python argparse_script.py --help usage: Commandline Calendar [-h] A simple utility to display a calendar . optional arguments: -h, --help show this help message and exit Full documentation available at http:www.example.com/
Adding arguments
The power of argparse
is in it’s ability to handle complex arguments. The calendar application we are building must be able to display the calendar of any month. In order to display the calendar of a given month, our program will need to know two things; the year and the month it must produce a calendar for. Let’s add additional code to add these two arguments.
Positional Arguments
argparse
Supports two types of arguments:
- Positional arguments and
- Optional arguments
Positional arguments are required arguments and they should be entered in the correct order. Adding a positional argument to the parser is simple:
parser.add_argument("foo", help="Help text for foo")
The code below, adds the month and year positional arguments.
import argparse parser = argparse.ArgumentParser() parser.prog = "Commandline Calendar" parser.description = "A simple utility to display a calendar." parser.epilog = "Full documentation available at http:www.example.com/" parser.add_argument("month", help="The month") parser.add_argument("year", help="The year") parser.parse_args()
The output:
terra@shadow:/tmp$ python argparse_script.py --help usage: Commandline Calendar [-h] month year A simple utility to display a calendar for the specified month. positional arguments: month The month year The year optional arguments: -h, --help show this help message and exit Full documentation available at http:www.example.com/
Running the program without any options or arguments generates an error that argparse
handles:
terra@shadow:/tmp$ python argparse_script.py usage: Commandline Calendar [-h] month year Commandline Calendar: error: too few arguments
This is much better than having to code that functionality ourselves. At this point, running the script and supplying it with a month and year like this
terra@shadow:/tmp$ python argparse_script.py January 2017
does nothing because we have not written any logic to handle those options yet.
Optional arguments
Optional arguments are arguments that are usually preceded by a double dash “--
” or a single dash “-
“. These can include a short alias. An example of an optional argument is the help argument that is invoked by typing -h
or --help
.
The syntax for creating optional arguments is:
parser.add_argument('-b','--bar', help="bar help")
Let’s add an optional verbosity option to our calendar program.
import argparse parser = argparse.ArgumentParser() parser.prog = "Commandline Calendar" parser.description = "A simple utility to display a calendar." parser.epilog = "Full documentation available at http:www.example.com/" parser.add_argument("month", help="The month") parser.add_argument("year", help="The year") parser.add_argument('-v','--verbose', help="Print calendar for the month", action="store_true") parser.parse_args()
The action="store_true"
part instructs the parser to set the Value of verbose
to True
if the --verbose
or -v
option is supplied.
In the first code sample, I mentioned that parser.parse_args()
returns a Namespace
object. This object is not unlike a Python dictionary. The Namespace
object returned by the parse_args()
method contains all the information received as arguments from the user. For our program to be useful, we must have a way to access the arguments our users will parse to the program. To do this, assign the return value of the parse_args()
method to a variable:
args = parser.parse_args()
This will enable us to ‘read’ the arguments supplied by accessing them using dot notation like this: args.month, args.year
or args.verbose
Our interface looks good now, we have two required arguments and one optional one:
terra@shadow:/tmp$ python argparse_script.py --help usage: Commandline Calendar [-h] [-v] month year A simple utility to display a calendar for the specified month. positional arguments: month The month year The year optional arguments: -h, --help show this help message and exit -v, --verbose Print calendar for the month Full documentation available at http:www.example.com/
We have successfully created an interface using argparse that takes care of input validation. Now let’s finish off the calendar application. I have added extra functionality and renamed the script to month_cal.py.
import argparse import calendar def get_args(): # Create a parser parser = argparse.ArgumentParser( prog="Calendar Utility", description="A simple utility to display a calendar for the specified month", epilog="Full documentation available at www.yoursite.com", usage="month_cal.py MONTH-NAME... YEAR...") # Positional arguments parser.add_argument( "month", help="The month") parser.add_argument( "year", type=int, help="The year") # Optional Argument parser.add_argument( "--verbose", "-v", help="Print out a calendar for the month.", action="store_true") args = parser.parse_args() return args def main(): args = get_args() month = args.month.capitalize() year = args.year # calendar requires month to be entered as an int months_list = dict((v, k) for k,v in enumerate(calendar.month_name)) if args.verbose: try: calendar.prmonth(year, months_list[month]) except KeyError: pass else: print("You entered %s %s";) %(month, year) if __name__ == '__main__': main()
Output without any verbosity.
terra@shadow:/tmp$ python month_cal.py October 2017 You entered October 2017
Output when verbosity is requested.
terra@shadow:/tmp$ python month_cal.py October 2017 --verbose October 2017 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
There is a lot more to argparse
that I did not cover here, such as handling conflicting options, creating argument groups and advanced argument handling. I recommend that you read more about it in the Python documentation. Thank you for reading.
very informative and well presented
Thank you! I’m glad you liked it.