Command-Line Scripts with argparse

Let users hand your script its inputs

Intermediate 11 min

In this lesson

argparse is Python’s built-in module for building command-line tools. A script you have to edit before every run isn’t really a tool — argparse lets users pass inputs on the command line (python clean.py report.csv --uppercase) and gives you help text and error messages for free. This lesson builds a small CLI step by step.

Explain it like I’m 5

Command-line arguments are the instructions you hand a script when you start it, like telling a vending machine which button you want instead of rewiring it each time.

From hardcoded values to arguments

The slow way is to edit variables in the file for every run. That’s fine once, but painful when the script becomes something you use daily. Command-line arguments let the user supply those values at launch instead, so the code stays put.

Example
# Hardcoded: you must open the file and edit it every time
filename = "report.csv"
uppercase = True
print("cleaning", filename, "uppercase =", uppercase)
Output
cleaning report.csv uppercase = True
Editing source for every run doesn't scale.

argparse: positionals, options, and flags

You create a parser, declare the arguments you expect, then call parse_args(). A positional argument is required and identified by position; an option (starting with --) is named and usually optional; a flag with action="store_true" is simply present or absent. Here we pass the arguments as a list so it runs in the browser, but on a real machine parse_args() reads them from the command line automatically.

Example
import argparse

parser = argparse.ArgumentParser(description="Clean a CSV file")
parser.add_argument("filename")                          # required positional
parser.add_argument("--uppercase", action="store_true")  # on/off flag

args = parser.parse_args(["report.csv", "--uppercase"])
print(args.filename, args.uppercase)
Output
report.csv True
filename is required; --uppercase is a True/False flag.
Example
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("name")
parser.add_argument("--times", type=int, default=1)

args = parser.parse_args(["Ada", "--times", "3"])
for _ in range(args.times):
    print("Hello", args.name)
Output
Hello Ada
Hello Ada
Hello Ada
type=int converts the value; default fills it in when omitted.

Build a tiny greeter CLI

Put the pieces together: one required value and one flag that changes behaviour.

Build a parser that takes a required name and an optional --shout flag. Start from f"Hello {args.name}", and when --shout is given, print the greeting in capitals.

import argparse

parser = argparse.ArgumentParser()
# TODO: add a positional "name" argument
# TODO: add an optional "--shout" flag (action="store_true")

args = parser.parse_args(["Ada", "--shout"])
greeting = f"Hello {args.name}"
# TODO: if args.shout, uppercase the greeting
print(greeting)

Common mistake: Reading sys.argv by index instead of using argparse

Why it happens:

sys.argv[1] looks simpler for one argument, so it sneaks in early.

How to fix it:

Use argparse as soon as you have more than one argument or any optional one. It handles order, defaults, types, missing values, and help — all the parts hand-rolled sys.argv code gets wrong.

Common mistake: Forgetting type= so numbers arrive as strings

Why it happens:

argparse hands you every value as a string by default, and "3" looks close enough to 3 until you do maths with it.

How to fix it:

Pass type=int (or type=float) so the value is converted for you and bad input is rejected with a clear message.

Common mistake: Expecting a flag to carry a value

Why it happens:

A store_true flag is either present or absent, but it’s easy to write --shout yes as if it took a word.

How to fix it:

For an on/off switch use action="store_true" and just include or omit the flag. Use a normal option (no store_true) when you actually need a value.

What does argparse generate automatically from your add_argument calls?

What is a flag created with action="store_true"?

Why pass type=int to an argument?

Mini exercise (medium)

Build a CLI that takes a required width and height as integers and an optional --unit (default "cm"), then prints the area like 20 sq cm. Parse the arguments ["5", "4"] so the default unit is used.

Do it here. Finish the code below and press Run to try your answer right in the browser — no setup needed.

import argparse

parser = argparse.ArgumentParser()
# TODO: add width and height as integers, and an optional --unit (default "cm")

args = parser.parse_args(["5", "4"])
area = 0  # TODO: width * height
print(f"{area} sq {args.unit}")

What to learn next

You turned a hardcoded script into a real command-line tool: positional arguments, optional -- options, on/off flags with store_true, type conversion with type=int, and the free -h help screen. You built a small greeter CLI that shouts on demand.

Now point that tool at files. File and Folder Automation with pathlib shows how to read a file’s name and extension, group files by type, and build a safe dry-run plan. When you’re ready, continue to the next lesson.