Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

For a new Python command-line program, use the standard-library argparse module: create an ArgumentParser, declare inputs with add_argument(), then call parse_args(). The result is a Namespace whose attributes contain converted and validated values. With no list supplied, parse_args() reads the process command line from sys.argv.

This pattern gives you positional arguments, options, type conversion, choices, generated help, usage text, and consistent error messages without installing a third-party package. The Python Argparse Tutorial and the argparse API reference document the interface.

A minimal working parser

Save this as add_numbers.py:

import argparse

parser = argparse.ArgumentParser(description="Add two integers.")
parser.add_argument("left", type=int, help="first integer")
parser.add_argument("right", type=int, help="second integer")
parser.add_argument("--verbose", action="store_true", help="show a labeled result")
args = parser.parse_args()

result = args.left + args.right
print(f"{args.left} + {args.right} = {result}" if args.verbose else result)

Run it with:

python add_numbers.py 12 30
python add_numbers.py 12 30 --verbose
python add_numbers.py --help

The first two tokens after the script name fill the required positional arguments left and right. type=int converts text from the shell into integers. The --verbose option is a Boolean flag: it is False unless present and True when supplied.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How argparse turns tokens into values

Create an ArgumentParser

argparse.ArgumentParser(description=...) creates the parser and supplies the description shown in generated help. Unless you provide a custom usage string, the parser derives usage from the arguments you declare.

Declare each input with add_argument()

A bare name such as filename declares a positional argument. Option strings begin with a hyphen, for example -o or --output. The declaration controls whether an input is required, how many tokens it consumes, its destination attribute, conversion, defaults, and help text.

Parse and read the Namespace

args = parser.parse_args() reads sys.argv when called without arguments. Access values as attributes such as args.filename, args.output, or args.verbose. To parse a controlled sequence instead, pass a list: parser.parse_args(["--verbose", "input.txt"]).

Positionals, options, and defaults

Required positional values

parser.add_argument("input_file", help="file to process")

A positional is required unless you change its cardinality with nargs. Users provide it by position, not with a flag: python tool.py report.csv.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Optional flags and values

parser.add_argument("-o", "--output", default="result.txt", help="output path")

Both -o value and --output value set the same attribute, args.output. Long names make commands self-documenting; short aliases are useful for frequently typed options.

Conversion, choices, and defaults

parser.add_argument("--port", type=int, default=8080)
parser.add_argument("--format", choices=["json", "csv"], default="json")

Shell arguments arrive as strings. The type callable converts them and causes a parser error when conversion fails. choices rejects values outside the listed set. A default is used when an option is omitted.

Flags, repeated values, and mutually exclusive options

Boolean and repeatable flags

Use action="store_true" for an on/off switch:

parser.add_argument("--dry-run", action="store_true")

For repeatable verbosity, use action="count":

parser.add_argument("-v", "--verbose", action="count", default=0)

Then -v, -vv, and -vvv produce 1, 2, and 3 respectively.

One option consuming several values

nargs controls how many tokens an argument consumes:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
parser.add_argument("--include", nargs="+", help="one or more patterns")
parser.add_argument("--define", nargs=2, metavar=("NAME", "VALUE"))

nargs="+" requires at least one value and returns a list. A numeric value such as 2 consumes exactly that many tokens. Other useful forms include ? for zero or one value and * for zero or more.

Mutually exclusive switches

mode = parser.add_mutually_exclusive_group()
mode.add_argument("--quiet", action="store_true")
mode.add_argument("--verbose", action="store_true")

The parser reports an error if a user supplies both flags. Add required=True to the group when exactly one choice must be selected.

Help text and invalid input

Every parser automatically supports --help (and typically -h). Running python your_script.py --help prints usage, the description, argument details, and exits. Missing required arguments, invalid integers, values outside choices, and unknown options produce a diagnostic with usage information rather than silently continuing. Add useful help= text because it becomes part of the command’s user interface.

For a custom command name or formatting, configure the parser:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
parser = argparse.ArgumentParser(
    prog="inventory",
    description="Inspect an inventory file.",
    epilog="Example: inventory items.csv --format json"
)

Testing and embedding a parser

Passing an explicit list avoids depending on the test runner’s own command line:

def build_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("source")
    parser.add_argument("--limit", type=int, default=10)
    return parser

def test_defaults():
    args = build_parser().parse_args(["items.csv"])
    assert args.source == "items.csv"
    assert args.limit == 10

Keeping parser construction in a function makes it reusable and keeps importing the module from unexpectedly parsing the host process’s arguments. In the executable portion of a script, call parsing and business logic from a main() function:

def main(argv=None):
    parser = build_parser()
    args = parser.parse_args(argv)
    # application logic here
    return 0

if __name__ == "__main__":
    raise SystemExit(main())

main(["items.csv", "--limit", "20"]) can now be exercised directly in a test.

Handling filenames that begin with a hyphen

A positional filename such as -f can look like an option. Insert -- before it to tell the parser that the remaining tokens are positional:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
python tool.py -- -f

In an explicit parse, parser.parse_args(["--", "-f"]) treats -f as the positional value. This delimiter is especially important for tools that process user-supplied paths.

Subcommands for multi-purpose tools

When one executable has distinct operations such as init, list, and delete, use subparsers so each operation has its own arguments:

import argparse

parser = argparse.ArgumentParser(prog="project")
commands = parser.add_subparsers(dest="command", required=True)

init_parser = commands.add_parser("init", help="create a project")
init_parser.add_argument("directory")

list_parser = commands.add_parser("list", help="list projects")
list_parser.add_argument("--all", action="store_true")

args = parser.parse_args()
if args.command == "init":
    print(f"Creating {args.directory}")
elif args.command == "list":
    print("Listing all" if args.all else "Listing active")

Each subparser contributes to the top-level help output and validates only the options relevant to its command.

Choosing argparse, optparse, or getopt

Need Suitable choice Reason
A new general-purpose script or command-line tool argparse The recommended standard-library parser with positionals, options, conversion, validation, help, and subcommands.
An established program built around older option behavior optparse or a planned migration Preserve compatibility while comparing the existing interface and required behavior before changing it.
C-style option processing or a deliberately low-level interface getopt The Python documentation describes it as a C-style parser and shows an argparse equivalent.

See Python’s command-line libraries overview and the getopt documentation for the alternatives. Do not migrate a stable interface solely for style; compatibility and user expectations matter.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common failures and fixes

“the following arguments are required”

A required positional or an option marked required=True is missing. Check the generated usage line and provide the value, or give the argument a default if omission is valid.

“invalid int value” (or another conversion error)

The token cannot be converted by the declared type. Pass a value in the expected format, or use a custom conversion function that raises argparse.ArgumentTypeError with a clearer explanation.

“unrecognized arguments”

The spelling, hyphen count, or placement is wrong, or a value was accidentally left outside the declaration. Run --help, verify every option name, and use -- when a positional begins with a hyphen. If a wrapper must forward unknown options, investigate parse_known_args() rather than ignoring the error blindly.

An option consumes the next option as its value

Check nargs and whether the value is missing. A declaration expecting one value will consume the next token; use a Boolean action for flags and provide an explicit value for value-taking options.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Parsing happens during import

Move parsing into main(argv=None) and call it under if __name__ == "__main__". This prevents libraries and test runners from inheriting your application’s argument parsing.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and maintenance

  • Runtime: argparse is part of Python’s standard library, so normal use adds no package installation step. Parsing is performed once at startup for typical command-line tools.
  • Reliability: Declare constraints close to the input with type, choices, nargs, and mutually exclusive groups so invalid combinations fail before application work begins.
  • Compatibility: Treat option names, defaults, and help text as a public interface. Renaming a flag can break shell scripts and automation.
  • Security: Validation is not authorization. Continue to validate paths, permissions, URLs, and other values according to the operation you perform.
  • Versioning: Check the documentation for the Python version your project supports. The unversioned Python documentation may describe a newer release than the 3.10 API reference.

Or skip the browser setup

If your CLI workflow also needs website screenshots for reports, visual tests, or documentation, ScreenshotNeo provides a single HTTP request instead of maintaining browser automation. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

See the ScreenshotNeo documentation for all request options. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

Frequently Asked Questions

What does argparse do when a user passes –help?

It prints the parser’s generated usage and help text, then exits successfully without running the rest of the command.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I keep a command-line parser out of library imports?

Yes. Build it in a function, accept an optional argument list, and invoke parsing only from a main() function guarded by if __name__ == “__main__”.

The Bottom Line

Start new Python command-line interfaces with argparse: declare arguments precisely, parse them once, validate early, and test with explicit argument lists.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.