Python CLI (argparse)
argparse 기반 Python CLI 도구 템플릿. 서브커맨드, 버전 출력, 오류 처리 패턴 포함.
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path
from typing import Optional
__version__ = "1.0.0"
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="mytool",
description="Brief description of your CLI tool.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
examples:
%(prog)s process input.txt -o output.txt
%(prog)s process input.txt --verbose --dry-run
%(prog)s validate config.yaml
""",
)
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
sub = parser.add_subparsers(dest="command", metavar="COMMAND", required=True)
p = sub.add_parser("process", help="Process a file")
p.add_argument("input", type=Path, help="Input file path")
p.add_argument("-o", "--output", type=Path, help="Output file path")
p.add_argument("-v", "--verbose", action="store_true")
p.add_argument("-n", "--dry-run", action="store_true")
v = sub.add_parser("validate", help="Validate a config file")
v.add_argument("config", type=Path, help="Config file path")
v.add_argument("--strict", action="store_true", help="Fail on warnings")
return parser
def cmd_process(args: argparse.Namespace) -> int:
if not args.input.exists():
print(f"error: {args.input} not found", file=sys.stderr)
return 1
if args.verbose:
print(f"processing {args.input} ...")
if args.dry_run:
print(f"[dry-run] would write to {args.output or args.input.with_suffix('.out')}")
return 0
dest = args.output or args.input.with_suffix(".out")
dest.write_bytes(args.input.read_bytes())
print(f"written → {dest}")
return 0
def cmd_validate(args: argparse.Namespace) -> int:
if not args.config.exists():
print(f"error: {args.config} not found", file=sys.stderr)
return 1
print(f"✓ {args.config} looks valid")
return 0
def main(argv: Optional[list] = None) -> int:
args = build_parser().parse_args(argv)
dispatch = {"process": cmd_process, "validate": cmd_validate}
return dispatch[args.command](args)
if __name__ == "__main__":
sys.exit(main())