silver and gold bicycle wheel
|

How to Use Argparser to Get Command Line Arguments in Python Scripts.

Argparser is a standard module to get the command line arguments when running a Python script. It’s a straightforward tool with a build-in help page generator.

Following is a simple example script that finds and replaces values in all the files of a directory. In this example, we use the subprocess module to execute the shell command in Python.

import argparse
import subprocess

# 1. Create an argument parser
parser = argparse.ArgumentParser(
    description="Find and replace old values with new ones in all the files in the directory"
)

# 2. Add arguments
parser.add_argument(
    "-d", "--directory", help="The directory to search", required=False, default="./"
)
parser.add_argument("-o", "--old", help="The old value", required=True)
parser.add_argument("-n", "--new", help="The new value", required=True)

# 3. Parse the arguments
args = parser.parse_args()

# Construct the linux command
# find [directory] -type f -exec sed -i 's/[old]/[new]/g' {} \;

command = [
    "find",
    args.directory,
    "-type",
    "f",
    "-exec",
    "sed",
    "-i",
    "s/" + args.old + "/" + args.new + "/g",
    "{}",
]

# Run the command
subprocess.run(command)

In the above example, we’ve covered three important steps to get command line inputs using the argparser module.

1. Creating an ArgumentParser object.

ArgumentParser object is fundamental to accepting command line arguments. There are many options to customize the command line app. In the example, we’ve set the description.

parser = argparse.ArgumentParser(
    description="Description about the program",
)

2. Add arguments to the app.

Here we configure what arguments our app accepts. Also, we can configure many options for every argument we accept. In the example, we’ve set the directory argument to be optional. (Technically, it’s not called an argument, it’s an option) We’ve given it a default value. We’ve also given a help text to explain what each argument is.

parser.add_argument(
    "-d", "--directory", help="The directory to search", required=False, default="./"
)
parser.add_argument("-o", "--old", help="The old value", required=True)
parser.add_argument("-n", "--new", help="The new value", required=True)

3. Parse the arguments

Parsing the arguments is what gives access to the user inputs inside the Python script. The parse_args method of the parser object returns another object. User inputs are embedded in it as properties of the object.

args = parser.parse_args()

How to edit the help information in argparser?

Command line tools created with argparser display help information as well. You can run the script with a -h option and access the help information.

Here’s the help info for the app we’ve created:

(env) $ python app.py -h
usage: app.py [-h] [-d DIRECTORY] -o OLD -n NEW

Description about the program

options:
  -h, --help            show this help message and exit
  -d DIRECTORY, --directory DIRECTORY
                        The directory to search
  -o OLD, --old OLD     The old value
  -n NEW, --new NEW     The new value
    ```

We've already given some of the information in our script. We've configured a description when we've created the Argparser object. This is displayed at the top of our rendered help document. 

We can configure a few other pieces of information here.

1. The usage example. 
Argparser module automatically generates a usage example at the top of the help message. 

2. Description. 
A detailed explanation of what this command is.

3. Epilog
A text to show at the end of the help message. We can use this space to display information not directly related to the command. For instance, developer credit. 

4. The formatter class
These classes determine how help messages appear and what information they show. You can select one of the four options available. 

argparse.RawDescriptionHelpFormatter argparse.RawTextHelpFormatter
argparse.ArgumentDefaultsHelpFormatter
argparse.MetavarTypeHelpFormatter

We can use the ArgumentDefaultHelpFormatter to show the default values along with arguments.

In the following example, we've configured all the four help generation tweaks we discussed. 

```python
parser = argparse.ArgumentParser(
    prog="replace",
    usage="%(prog)s [options]",
    description="This utility finds a word in every file in a directory and replaces it with another word.",
    epilog="Developed by Thuwarakesh Murallie",
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)

The help message looks like this now.

(env) $ python app2.py -h
usage: replace [options]

This utility finds a word in every file in a directory and replaces it with another word.

options:
  -h, --help            show this help message and exit
  -d DIRECTORY, --directory DIRECTORY
                        The directory to search (default: ./)
  -o OLD, --old OLD     The old value (default: None)
  -n NEW, --new NEW     The new value (default: None)

Developed by Thuwarakesh Murallie

Restrict command line argument values.

Sometimes, we don’t need the user to input arbitrary values to the arguments. We may want to restrict the values to be in a predefined set or in a range.

The argparser’s add_argument method has a parameter called choices. We can pass a list, set, or a tuple to restrict input values.

parser.add_argument(
    "-n",
    "--new",
    help="The new value",
    required=True,
    choices=[
        "Orenge",
        "Apple",
        "Banana",
        "Cherry",
        "Grape",
        "Lemon",
    ],
)

Attempting to insert a value not in the list will result in an error:

(env) $ python app2.py -o apples -n Apricot
usage: replace [options]
replace: error: argument -n/--new: invalid choice: 'Apricot' (choose from 'Orenge', 'Apple', 'Banana', 'Cherry', 'Grape', 'Lemon')

Yet, there isn’t a straightforward method to restrict numeric inputs to a range. If we need it, we need to handle it inside our application.

parser.add_argument(
    "-a", "--age", help="The age of the person", required=True, type=int
)

args = parser.parse_args()


if args.age < 18:
    print("You are not allowed to use this program")
    exit(1)

Converting arguments to desired data types

Argparser assumes everything the user insert is a string. But we can change it. We can configure the argparser’s add_argument method to convert user inserts to specific types.

The following is an argument to accept weight, which is a float.

parser.add_argument(
    "-w", "--weight", help="The weight of the person", required=True, type=float
)

How to take a file as command line argument

The type parameter of the argparser’s add_argument method also accepts open or FileType as inputs.

For instance, the following Python script takes a file as input and counts the number of words in that file.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-f", "--file", required=True, type=open)

args = parser.parse_args()

file_content = args.file.read()

print(len(file_content.split()))
(env) $ python app2.py -f sample.txt
10

When the type is set to ‘open’, argparser will open the file on read-only mode. To also write back to the file, you should use the argparser.FileType with a ‘w’.

parser.add_argument('output', type=argparse.FileType('w'))

Conclusion,

Argparser is a convenient tool to accept command-line arguments in Python.

This post discussed how we could use argparser to accept inputs, restrict inputs to a set of values or in a range, configure the help message, and accept files as inputs.

Argparser is a Python standard model. Thus, it’s very popular compared. Yet, check out Typer, because it has a friendly way to develop more complex command line tools.

Similar Posts