Python Boilerplate
Boilerplate to start a Python script for Python versions at or above 3.7.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
myscript.py
Description:
Short description of what this script does.
Usage:
python myscript.py -i input.txt -o output.txt -v
Requirements:
Python >= 3.7
"""
import argparse
import logging
import os
import sys
from pathlib import Path
from typing import Optional
__version__ = "0.1.0"
# ---------------- Logging ----------------
def setup_logging(verbose: bool = False) -> None:
"""Configure logging format and level."""
log_level = logging.DEBUG if verbose else logging.INFO
logging.basicConfig(
level=log_level,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
# ---------------- CLI ----------------
def parse_args() -> argparse.Namespace:
"""Parse command line arguments."""
parser = argparse.ArgumentParser(
description="Example Python script boilerplate",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("-i", "--input", required=True, help="Input file")
parser.add_argument("-o", "--output", help="Output file (default: stdout)")
parser.add_argument("-n", "--dry-run", action="store_true", help="Dry-run mode")
parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging")
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
return parser.parse_args()
# ---------------- Helpers ----------------
def run_task(input_file: Path, output_file: Optional[Path], dry_run: bool = False) -> None:
"""Main processing logic goes here."""
logging.info("Processing input: %s", input_file)
if not input_file.exists():
logging.error("Input file does not exist: %s", input_file)
sys.exit(1)
# Example: prefix each line with line numbers
with input_file.open("r", encoding="utf-8") as fin:
lines = [f"{idx+1}: {line}" for idx, line in enumerate(fin)]
if dry_run:
logging.info("Dry-run enabled, not writing output")
return
if output_file:
with output_file.open("w", encoding="utf-8") as fout:
fout.writelines(lines)
logging.info("Wrote output to %s", output_file)
else:
sys.stdout.writelines(lines)
# ---------------- Main ----------------
def main() -> None:
args = parse_args()
setup_logging(args.verbose)
input_path = Path(args.input)
output_path = Path(args.output) if args.output else None
try:
run_task(input_path, output_path, dry_run=args.dry_run)
except Exception as e:
logging.exception("Unhandled exception: %s", e)
sys.exit(1)
if __name__ == "__main__":
main()