Code of the Day
BeginnerAutomation Thinking

Building a CLI script

Structure a Python script with a main() function, argparse for flags, and the if __name__ == '__main__' guard.

WorkflowBeginner10 min read
By the end of this lesson you will be able to:
  • Structure a Python script with a main() function
  • Explain why if __name__ == '__main__' matters
  • Add a --dry-run flag with argparse
  • Print clear progress output during a bulk operation

The difference between a script and a tool is structure. A script is a file of statements you run once; a tool is something you run repeatedly, with options, by callers who depend on its to know if it succeeded. people other than you. The gap is smaller than it sounds — it's mostly a main() function and argparse.

The main() function

Wrap all your logic in a main() function and call it at the bottom:

def main():
    print("doing the work...")

if __name__ == "__main__":
    main()

This is the canonical Python script structure. The logic lives in main(), which makes it testable (you can import and call main() from a test file) and readable (the function name documents the intent).

Why if name == 'main' matters

Every Python file has a built-in __name__ variable. When you run a file directly (python my_script.py), Python sets __name__ to "__main__". When you import it (import my_script), Python sets __name__ to the module name instead.

The guard if __name__ == "__main__": means "only run this block if this file was executed directly, not imported." Without it, importing your module as a library would immediately execute your script logic — renaming files, writing output, making network requests — which is almost never what you want.

Adding flags with argparse

argparse is the standard library module for parsing command-line arguments. A --dry-run flag is the minimum useful addition to any script that modifies data:

import argparse

def parse_args():
    parser = argparse.ArgumentParser(description="Process CSV files.")
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Print what would happen without doing it.",
    )
    parser.add_argument(
        "input_dir",
        help="Directory containing input CSV files.",
    )
    return parser.parse_args()

def main():
    args = parse_args()
    print(f"Input dir : {args.input_dir}")
    print(f"Dry run   : {args.dry_run}")
    # rest of the logic here

if __name__ == "__main__":
    main()

action="store_true" means the flag is a boolean: present means True, absent means False. argparse also automatically generates a --help message from the help= strings — run any argparse script with --help to see it.

Keep parse_args() separate from main(). It makes testing easier: you can call main() with pre-built args without going through the argument parser.

A complete skeleton

Here is the full pattern put together. Try running it, then modify the logic:

Python — editable, runs in your browser

The runner simulates the argparse output with a plain class so you can focus on the structure without the full CLI machinery. In a real script you replace Args() with parse_args().

Where to go next

Next: lab — automate a task — put everything together by writing a complete script that reads a CSV, filters and counts records, and prints a summary report.

Finished reading? Mark it complete to track your progress.

On this page