To begin, we import print_function and the argparse module. By importing the print_function from the __future__ library we can write print statements as they are written in Python 3.X but still run them in Python 2.X. This allows us to make recipes compatible with both Python 2.X and 3.X. Where possible, we carry this through with most recipes in the book.
After creating a few descriptive variables about the recipe, we initialize our ArgumentParser instance. Within the constructor, we define the description and epilog keyword arguments. This data will display when the user specifies the -h argument and can give the user additional context about the script being run. The argparse library is very flexible and can scale in complexity if required for a script. Throughout this book, we cover many of the library's different features, which are detailed on its document page:
from __future__ import print_function
import argparse
__authors__ = ["Chapin Bryce", "Preston Miller"]
__date__ = 20170815
__description__ = 'A simple argparse example'
parser = argparse.ArgumentParser(
description=__description__,
epilog="Developed by {} on {}".format(
", ".join(__authors__), __date__)
)
With the parser instance created, we can now begin adding arguments to our command-line handler. There are two types of arguments: positional and optional. Positional arguments start with an alphabetic character, unlike optional arguments, which start with a dash, and are required to execute the script. Optional arguments start with a single or double dash character and are non-positional (that is, the order does not matter). These characteristics can be manually specified to overwrite the default behavior we’ve described if desired. The following code block illustrates how to create two positional arguments:
# Add Positional Arguments
parser.add_argument("INPUT_FILE", help="Path to input file")
parser.add_argument("OUTPUT_FILE", help="Path to output file")
In addition to changing whether an argument is required, we can specify help information, create default values, and other actions. The help parameter is useful in conveying what the user should provide. Other important parameters are default, type, choices, and action. The default parameter allows us to set a default value, while type converts the type of the input, which is a string by default, to the specified Python object type. The choices parameter uses a defined list, dictionary, or set to create valid options the user can select from.
The action parameter specifies the type of action that should be applied to a given argument. Some common actions include store, which is the default and stores the passed value associated with the argument; store_true, which assigns True to the argument; and version, which prints the version of the code specified by the version parameter:
# Optional Arguments
parser.add_argument("--hash", help="Hash the files", action="store_true")
parser.add_argument("--hash-algorithm",
help="Hash algorithm to use. ie md5, sha1, sha256",
choices=['md5', 'sha1', 'sha256'], default="sha256"
)
parser.add_argument("-v", "--version", "--script-version",
help="Displays script version information",
action="version", version=str(__date__)
)
parser.add_argument('-l', '--log', help="Path to log file", required=True)
With our arguments defined and configured, we can now parse them and use the provided inputs in our code. The following snippet shows how we can access the values and test whether the user specified an optional argument. Notice how we refer to arguments by the name we assign them. If we specify a short and long argument name, we must use the long name:
# Parsing and using the arguments
args = parser.parse_args()
input_file = args.INPUT_FILE
output_file = args.OUTPUT_FILE
if args.hash:
ha = args.hash_algorithm
print("File hashing enabled with {} algorithm".format(ha))
if not args.log:
print("Log file not defined. Will write to stdout")
When combined into a script and executed at the command line with the -h argument, the preceding code will provide the following output:
As seen here, the -h flag displays the script help information, automatically created by argparse, along with the valid options for the --hash-algorithm argument. We can also use the -v option to display the version information. The --script-version argument displays the version in the same manner as the -v or -version arguments as shown here:
The following screenshot shows the message printed to the console when we select one of our valid hashing algorithms: