CLI Tools with argparse & Click
Also Known As
argparse
Click
Typer
Python CLI
command line
TL;DR
Building Python command-line tools — argparse (stdlib) for simple tools, Click (decorator-based) for complex CLIs with subcommands, type coercion, and better help formatting.
Explanation
argparse (stdlib): define arguments programmatically, automatic --help, type conversion, positional vs optional arguments. Click: decorator-based (@click.command, @click.option, @click.argument), composable subcommand groups, automatic prompting, password hiding, file handling, and better error messages. Typer: Click wrapper with type hints — Python type annotations define CLI arguments. Use argparse for simple scripts, Click/Typer for complex tools distributed as packages. Both generate --help automatically from function docstrings and argument definitions.
Common Misconception
✗ sys.argv is sufficient for CLI argument parsing — sys.argv requires manual parsing with no type conversion, validation, or --help generation; argparse/Click handle all of this automatically.
Why It Matters
A well-built CLI tool with --help, type validation, and informative errors is as important as the tool's functionality — poor CLI UX makes good tools hard to use and hard to script.
Common Mistakes
- Parsing sys.argv manually instead of using argparse/Click.
- No input validation — argparse type= parameter handles this automatically.
- Missing default values — always provide defaults or mark arguments as required explicitly.
- No subcommands for multi-action tools — Click's @click.group() organises complex CLIs cleanly.
Code Examples
✗ Vulnerable
# Manual sys.argv parsing — fragile:
import sys
if len(sys.argv) < 3:
print('Usage: tool.py input output')
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
# No type checking, no --help, no --verbose flag support
✓ Fixed
import click
@click.group()
@click.option('--verbose', '-v', is_flag=True, help='Enable verbose output')
@click.pass_context
def cli(ctx, verbose):
ctx.ensure_object(dict)
ctx.obj['VERBOSE'] = verbose
@cli.command()
@click.argument('input', type=click.Path(exists=True))
@click.argument('output', type=click.Path())
@click.option('--format', type=click.Choice(['json', 'csv']), default='json')
@click.pass_context
def process(ctx, input, output, format):
if ctx.obj['VERBOSE']: click.echo(f'Processing {input} -> {output}')
# Auto --help generated from docstring
if __name__ == '__main__': cli()
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
26
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 7
Perplexity 4
Google 4
Ahrefs 2
Unknown AI 2
Also referenced
How they use it
crawler 18
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Low
⚡ Quick Fix
Use argparse or Click for CLI argument parsing — they auto-generate help text, validate types, and handle --verbose --quiet flags without custom parsing code
📦 Applies To
python 3.6
cli
🔗 Prerequisites
🔍 Detection Hints
sys.argv manual parsing; no --help flag; no argument validation; no subcommand support for complex CLI tools
Auto-detectable:
✗ No
pylint
mypy
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File