Command-line interfaces (CLIs) are how developers interact with tools daily. Python’s argparse (stdlib) and click (third-party) make building CLIs straightforward.

argparse — Standard Library

  # greet.py
import argparse

def main():
    parser = argparse.ArgumentParser(
        description="Greet people from the command line.",
    )
    parser.add_argument("name", help="Name to greet")
    parser.add_argument(
        "--count", "-c", type=int, default=1,
        help="Number of times to greet",
    )
    parser.add_argument(
        "--loud", action="store_true",
        help="Greet loudly (uppercase)",
    )

    args = parser.parse_args()
    greeting = f"Hello, {args.name}!"

    if args.loud:
        greeting = greeting.upper()

    for _ in range(args.count):
        print(greeting)

if __name__ == "__main__":
    main()
  

Usage:

  python greet.py Alice
python greet.py Bob --count 3 --loud
python greet.py --help
  

Subcommands

  def main():
    parser = argparse.ArgumentParser(prog="tool")
    subparsers = parser.add_subparsers(dest="command", required=True)

    # create command
    create_parser = subparsers.add_parser("create", help="Create a resource")
    create_parser.add_argument("name")

    # delete command
    delete_parser = subparsers.add_parser("delete", help="Delete a resource")
    delete_parser.add_argument("id", type=int)

    args = parser.parse_args()

    if args.command == "create":
        print(f"Creating {args.name}")
    elif args.command == "delete":
        print(f"Deleting ID {args.id}")
  
  python tool.py create myproject
python tool.py delete 42
  

Click — Elegant CLI Framework

  pip install click
  
  import click

@click.group()
def cli():
    """My CLI tool."""
    pass

@cli.command()
@click.argument("name")
@click.option("--count", "-c", default=1, help="Number of greetings")
@click.option("--loud", is_flag=True, help="Greet loudly")
def greet(name, count, loud):
    """Greet someone."""
    greeting = f"Hello, {name}!"
    if loud:
        greeting = greeting.upper()
    for _ in range(count):
        click.echo(greeting)

@cli.command()
@click.argument("filename", type=click.Path(exists=True))
@click.option("--format", type=click.Choice(["json", "csv"]), default="json")
def convert(filename, format):
    """Convert a file to another format."""
    click.echo(f"Converting {filename} to {format}")

if __name__ == "__main__":
    cli()
  
  python cli.py greet Alice --count 3 --loud
python cli.py convert data.csv --format json
python cli.py --help
  

Interactive Prompts

  import click

@click.command()
def setup():
    name = click.prompt("Project name")
    use_docker = click.confirm("Use Docker?")
    env = click.prompt(
        "Environment",
        type=click.Choice(["dev", "staging", "prod"]),
        default="dev",
    )
    click.echo(f"Setting up {name} ({env}), Docker: {use_docker}")
  

Progress Bars

  import click
import time

@click.command()
def process():
    items = range(100)
    with click.progressbar(items, label="Processing") as bar:
        for item in bar:
            time.sleep(0.01)
  

Packaging as an Installable CLI

In pyproject.toml:

  [project.scripts]
mytool = "myapp.cli:main"
  

After pip install -e ., run from anywhere:

  mytool greet Alice
  

argparse vs Click

Feature argparse Click
Dependency stdlib third-party
Syntax verbose decorator-based
Subcommands manual setup built-in groups
Colors/prompts manual built-in
Testing parse_args() CliRunner
  # Testing Click apps
from click.testing import CliRunner

def test_greet():
    runner = CliRunner()
    result = runner.invoke(greet, ["Alice", "--loud"])
    assert result.exit_code == 0
    assert "HELLO, ALICE!" in result.output
  

CLIs are the fastest way to automate workflows and share tools with your team.