argparse - Documentation

What is argparse?

argparse is a module in Python’s standard library that’s designed to create user-friendly command-line interfaces (CLIs). It allows you to easily define arguments your script accepts, automatically generate help and usage messages, and handle argument parsing with minimal code. Instead of manually parsing sys.argv, argparse provides a structured and intuitive way to manage command-line options and their associated values. This leads to cleaner, more maintainable, and easier-to-use scripts.

Why use argparse?

Using argparse offers several significant advantages:

argparse vs. other command-line parsing modules

While other modules exist for parsing command-line arguments in Python (e.g., getopt, optparse), argparse is generally preferred due to its ease of use, extensive features, and clear error handling. getopt is a more basic module, suitable for simpler scripts, while optparse is now deprecated in favor of argparse. argparse provides a superior balance of simplicity and power, making it the best choice for most command-line applications.

Installation and Setup

argparse is part of Python’s standard library, so there’s no need for separate installation. It’s available in all standard Python installations (Python 3.2 and later). To use it, simply import the module into your script:

import argparse

No further setup is required. You can immediately begin defining your command-line arguments using the ArgumentParser class and its associated methods.

Basic Usage

Creating an ArgumentParser object

The first step in using argparse is to create an ArgumentParser object. This object will hold the definition of your command-line arguments. Optionally, you can provide a description of your program as a string to the constructor. This description will be included in the help message.

import argparse

parser = argparse.ArgumentParser(description='A simple example program.')

Adding arguments with add_argument()

You add arguments to the ArgumentParser object using the add_argument() method. This method takes several important parameters:

Example:

parser.add_argument("filename", help="The input filename")
parser.add_argument("-o", "--output", help="The output filename", default="output.txt")
parser.add_argument("-v", "--verbose", action="store_true", help="Increase output verbosity")
parser.add_argument("-n", "--numbers", type=int, action="append", help="Add numbers to a list")

Parsing arguments with parse_args()

Once you’ve defined all your arguments, you parse the command-line arguments using the parse_args() method. This method returns a Namespace object containing the parsed arguments.

args = parser.parse_args()

Accessing parsed arguments

You can access the parsed arguments using the dot notation on the Namespace object. For example, if you added an argument named filename, you would access it using args.filename.

print(f"Input filename: {args.filename}")
print(f"Output filename: {args.output}")
print(f"Verbose mode: {args.verbose}")
print(f"Numbers: {args.numbers}")

A simple example

This example shows a complete program using argparse:

import argparse

parser = argparse.ArgumentParser(description='Add two numbers.')
parser.add_argument('a', type=int, help='First number')
parser.add_argument('b', type=int, help='Second number')

args = parser.parse_args()
result = args.a + args.b
print(f"The sum is: {result}")

To run this, save it as a Python file (e.g., adder.py) and then execute it from your terminal like this: python adder.py 5 10. The output will be “The sum is: 15”. Running python adder.py -h will show the help message.

Argument Types and Options

Positional arguments

Positional arguments are required arguments that must be provided in the command line in the order they are defined. They are specified in add_argument() without any leading hyphens (- or --). The order in which they appear in your script dictates the order in which they must be supplied on the command line.

parser.add_argument("filename", help="Input filename")
parser.add_argument("output_dir", help="Output directory")

# Usage: my_script.py input.txt /path/to/output

Optional arguments

Optional arguments are not required and can be omitted from the command line. They are specified with hyphens (- for short options) or double hyphens (-- for long options).

parser.add_argument("-v", "--verbose", action="store_true", help="Increase verbosity")
parser.add_argument("-o", "--output", help="Output file (optional)")

# Usage: my_script.py -v  or my_script.py --verbose --output output.txt or my_script.py input.txt -o results.txt

Short and long option names

Optional arguments can have both short (single-hyphen) and long (double-hyphen) option names. Short options are typically single letters, while long options are more descriptive.

parser.add_argument("-f", "--file", help="Input file") # -f and --file are both valid

Data types: strings, integers, floats, booleans

argparse automatically handles several common data types. You specify the type using the type argument in add_argument(). If no type is specified, strings are assumed.

parser.add_argument("count", type=int, help="Number of iterations")  # Integer
parser.add_argument("--value", type=float, help="Floating-point value") # Float
parser.add_argument("--enabled", action="store_true", help="Enable feature") # Boolean (True if present)
parser.add_argument("--disabled", action="store_false", help="Disable feature", default=True) # Boolean (False if present)

Note that store_true and store_false actions implicitly handle boolean values; you do not need to specify type=bool with them. Instead, they create a flag that changes the value.

Choices for arguments

You can restrict the values an argument can accept using the choices argument.

parser.add_argument("--level", choices=["low", "medium", "high"], help="Log level")

Attempting to use a value not in the list will result in an error.

Default values for arguments

You can specify a default value for an argument using the default argument. This value will be used if the argument is not provided on the command line.

parser.add_argument("--port", type=int, default=8080, help="Port number (default: 8080)")

Required arguments

You can make an optional argument required by setting required=True.

parser.add_argument("--config", required=True, help="Path to configuration file")

This will cause parse_args() to raise an error if the argument isn’t provided. Note that positional arguments are implicitly required unless a default is provided.

Argument help text

The help argument in add_argument() is crucial for providing clear instructions to the user. The text provided here will be included in the automatically generated help message (-h or --help). Write concise and informative help messages to improve the usability of your CLI.

Advanced Usage

Using action arguments

The action argument in add_argument() controls how the argument values are handled. Beyond the basic 'store' action (the default), several other actions offer powerful functionalities.

Store actions: store, store_true, store_false

parser.add_argument("--verbose", action="store_true", help="Enable verbose output")
parser.add_argument("--debug", action="store_false", dest="verbose", help="Disable verbose output") #Note the dest

Append actions: append, append_const

parser.add_argument("--option", action="append", help="Add an option (can be repeated)")
parser.add_argument("--include", action="append_const", const="value", help="Append value to list")

Count action

'count' increments a counter each time the option is encountered.

parser.add_argument("-v", "--verbose", action="count", help="Increase verbosity (can be repeated)")

args.verbose will be an integer representing the number of times -v or --verbose was specified.

Custom actions

You can create custom actions by subclassing argparse.Action. This allows you to define highly specialized argument handling.

class CustomAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        # Custom argument processing logic here
        setattr(namespace, self.dest, values.upper()) #Example custom action to uppercase value


parser.add_argument("--custom", action=CustomAction, help="A custom action")

Subparsers: Creating subcommands

Subparsers allow you to create complex CLIs with nested commands.

subparsers = parser.add_subparsers(dest="command", help="Available commands")

parser_a = subparsers.add_parser("a", help="Command A help")
parser_a.add_argument("arg_a", help="Argument for command A")

parser_b = subparsers.add_parser("b", help="Command B help")
parser_b.add_argument("arg_b", help="Argument for command B")

This creates a CLI with commands a and b.

Argument groups

Argument groups allow you to logically group related arguments in the help message.

group = parser.add_argument_group("Input Options", "Options related to input data")
group.add_argument("--input_file", help="Input file")
group.add_argument("--input_format", help="Input format")

Mutually exclusive groups

Mutually exclusive groups enforce that only one argument from a group can be specified.

group = parser.add_mutually_exclusive_group()
group.add_argument("--option_a", action="store_true", help="Option A")
group.add_argument("--option_b", action="store_true", help="Option B")

Handling errors

argparse automatically handles many common errors (e.g., missing required arguments, invalid argument types). It generates helpful error messages.

Custom error handling

For more specialized error handling, you can use try-except blocks to catch argparse.ArgumentError or other exceptions.

try:
    args = parser.parse_args()
    # Your code here
except argparse.ArgumentError as e:
    print(f"Error: {e}")

Argument parsing from files

argparse doesn’t directly support parsing arguments from files. However, you can achieve this by reading the file’s contents and then parsing them using parser.parse_args(args=file_content.split()). Note that this requires carefully formatting the file to mimic command-line arguments.

Formatting and Output

Formatting help messages

argparse automatically generates help messages that describe your program’s arguments. The format of these messages can be customized to a degree. The default formatting is generally sufficient for simple scripts, but for more complex applications, you might want to adjust the presentation.

Customizing help text

You can customize the help text displayed by providing a description to the ArgumentParser constructor and help text to the add_argument() method for each argument. The help text for an argument should be concise and clearly explain its purpose and usage. The description for the parser provides a broader overview of the program’s functionality.

parser = argparse.ArgumentParser(description="This is a description of my program.",
                                 formatter_class=argparse.RawTextHelpFormatter) #Example of a formatter
parser.add_argument("input", help="Path to the input file.  Must be a valid CSV.")

Using formatters

argparse provides several formatter classes to control the layout of the help messages:

You choose a formatter by specifying the formatter_class argument when creating the ArgumentParser object.

parser = argparse.ArgumentParser(description="My program", formatter_class=argparse.ArgumentDefaultsHelpFormatter)

Generating usage messages

The usage message shows users a basic example of how to run the program. It is typically included at the beginning of the help message. You can customize it using the usage argument in the ArgumentParser constructor. If you don’t provide a usage string, argparse will generate one based on your arguments.

parser = argparse.ArgumentParser(usage='%(prog)s [options] input_file', description="My program")

%(prog)s is a placeholder that will be replaced with the program’s name.

Adding version information

You can add version information to your CLI’s help message by using the version argument in the ArgumentParser constructor and then calling parser.parse_args() with the version argument.

parser = argparse.ArgumentParser(prog='myprogram', description='My Program Description', version='%(prog)s 1.0')
args = parser.parse_args(['--version']) # Accessing version info via --version
print(args)

This allows users to check the version using myprogram --version or myprogram -V. The version argument should be a string containing version information. Using %(prog)s will insert the program name.

Best Practices and Examples

Designing user-friendly command-line interfaces

Creating a user-friendly CLI involves careful consideration of several factors:

Best practices for argument naming and organization

Example: Complex command-line application

This example demonstrates a more complex CLI with subcommands and argument groups:

import argparse

parser = argparse.ArgumentParser(description="A complex command-line application")
subparsers = parser.add_subparsers(dest="command", help="Available commands")

# Subcommand: process
parser_process = subparsers.add_parser("process", help="Process data")
parser_process.add_argument("input_file", help="Input file path")
parser_process.add_argument("-o", "--output_dir", default=".", help="Output directory")

input_group = parser_process.add_argument_group("Input Options", "Options related to input data")
input_group.add_argument("--format", choices=["csv", "json"], default="csv", help="Input file format")

#Subcommand: analyze
parser_analyze = subparsers.add_parser("analyze", help="Analyze processed data")
parser_analyze.add_argument("input_file", help="Input file path (processed data)")
parser_analyze.add_argument("--threshold", type=float, default=0.5, help="Analysis threshold")

args = parser.parse_args()

# Process arguments based on the chosen command
if args.command == "process":
    print(f"Processing data from {args.input_file} to {args.output_dir}")
elif args.command == "analyze":
    print(f"Analyzing data from {args.input_file} with threshold {args.threshold}")

Example: Configuration file parsing

While argparse doesn’t directly parse config files, you can combine it with a config file parser (like configparser or toml) to create a flexible CLI:

import argparse
import configparser

parser = argparse.ArgumentParser(description="Program using config file")
parser.add_argument("--config", default="config.ini", help="Path to config file")
args = parser.parse_args()

config = configparser.ConfigParser()
config.read(args.config)

# Access config values
input_file = config["DEFAULT"]["input_file"]
output_dir = config["DEFAULT"]["output_dir"]
print(f"Using input file: {input_file}, output directory: {output_dir}")

This shows how to use command-line arguments (here, the config file path) to control the settings read from a configuration file. The command-line arguments provide overrides for the default values specified in the configuration file.

Appendix

Commonly used arguments and options

This section summarizes frequently used arguments and options within argparse:

Argument/Option Description Example
ArgumentParser() Creates the argument parser object. parser = argparse.ArgumentParser()
add_argument() Adds an argument to the parser. parser.add_argument("filename", help="Input file")
description Description of the program (in ArgumentParser()). parser = argparse.ArgumentParser(description="My program")
help Help text for an argument. parser.add_argument("-v", help="Verbose mode")
action Specifies how the argument is handled (store, store_true, store_false, append, count, etc.). parser.add_argument("-v", action="store_true")
type Specifies the data type of the argument (int, float, str, etc.). parser.add_argument("--count", type=int)
default Default value if the argument is not provided. parser.add_argument("--port", default=8080)
required Indicates if the argument is required. parser.add_argument("--config", required=True)
choices Restricts the argument to a set of choices. parser.add_argument("--level", choices=["low", "high"])
metavar Specifies the name to be displayed in the help message for the argument. parser.add_argument("file", metavar="FILE")
dest The name used to store the value in the namespace (used with some actions). parser.add_argument("-o", "--output", dest="outfile")
formatter_class Specifies the help message formatter. parser.add_argument(formatter_class=argparse.RawTextHelpFormatter)
parse_args() Parses the command-line arguments. args = parser.parse_args()
add_argument_group() Creates a group of related arguments. group = parser.add_argument_group("Input", "Input options")
add_mutually_exclusive_group() Creates a group where only one argument can be specified. group = parser.add_mutually_exclusive_group()
add_subparsers() Creates subcommands. subparsers = parser.add_subparsers()

Troubleshooting common issues

For more detailed error messages, use the -v or --verbose flag with the Python interpreter, or add explicit error handling as shown in the previous section.

Further reading and resources

Remember to consult the official documentation for the most accurate and up-to-date information.