How to Build an argparse Command-Line Tool in Python
Create a simple file-info CLI with argparse that counts lines and prints file size, with optional verbose and output flags.
Python code
51 linesimport argparse
import os
from pathlib import Path
def process_file(filepath, verbose=False):
"""Read a file and report its size and line count."""
path = Path(filepath)
if not path.exists():
raise FileNotFoundError(f"File not found: {filepath}")
content = path.read_text()
lines = content.splitlines()
size_kb = path.stat().st_size / 1024
if verbose:
print(f"Processing: {path}")
print(f"Lines: {len(lines)}")
print(f"Size: {size_kb:.2f} KB")
else:
print(f"{path}: {len(lines)} lines, {size_kb:.2f} KB")
def main():
parser = argparse.ArgumentParser(
description="Simple file info utility - counts lines and size"
)
parser.add_argument("filepath", type=str, help="Path to the file to analyze")
parser.add_argument(
"-v", "--verbose", action="store_true", help="Show extended processing details"
)
parser.add_argument(
"-o", "--output", type=str, default=None, help="Write result to a file (optional)"
)
args = parser.parse_args()
try:
if args.output:
with open(args.output, "w") as f:
f.write(process_file(args.filepath, verbose=args.verbose))
else:
process_file(args.filepath, verbose=args.verbose)
except FileNotFoundError as e:
print(f"Error: {e}")
return 1
return 0
if __name__ == "__main__":
exit(main())
Output
$ python file_info.py sample.txt
sample.txt: 12 lines, 1.23 KB
$ python file_info.py sample.txt --verbose
Processing: sample.txt
Lines: 12
Size: 1.23 KB
$ python file_info.py missing.txt
Error: File not found: missing.txt
How it works
The argparse module parses command-line arguments from sys.argv automatically when you call parse_args(). The add_argument method defines each expected flag or positional argument — here filepath is required, while -v/--verbose uses action='store_true' to act as a boolean switch. In main(), we call parse_args() to get an object holding the parsed values, then run our logic. The function returns an exit code (0 on success, 1 on file error) which the shell can use to detect whether the script succeeded. Wrapping the work in a main() function keeps the script importable and testable, while the if __name__ == '__main__': guard ensures it only runs when executed directly.
Common mistakes
- Using `action='store'` instead of `action='store_true'` for flags
- Forgetting to handle `FileNotFoundError` and letting the script crash
- Writing output with `print()` instead of returning a string for redirection
- Hardcoding paths instead of accepting them as positional arguments
Variations
- Use `nargs='?'` to make the filepath optional and read from stdin instead
- Add `type=Path` (from pathlib) instead of `type=str` for better type hints
Real-world use cases
- A support script that audits log files on a server to report line counts and sizes before debugging.
- A build-hook tool developers run locally to validate config files and print formatted summaries.
- A cron job wrapper that logs file growth metrics and streams output to a monitoring dashboard.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.