Building Command-Line Tools with Python: A Practical Guide

Introduction

Learn to create powerful, user-friendly CLI tools in Python using argparse, click, and best practices.

Written At

2025-06-17

Updated At

2025-06-17

Reading time

7 minutes

Step 1: Set Up Your Python Environment

Why it matters: A clean environment avoids dependency conflicts and makes your tool portable.

What to do:

  1. Install Python 3.8+ from python.org.
  2. Create a virtual environment:
    bash
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate

Example:

Your shell prompt should show (venv) when activated.

Step 2: Create a Basic CLI with argparse

Why it matters: argparse is built-in and great for simple tools.

What to do:

  1. Write a script that accepts arguments:
    python
    import argparse
    
    parser = argparse.ArgumentParser(description='Greet the user.')
    parser.add_argument('--name', required=True, help='Your name')
    args = parser.parse_args()
    print(f'Hello, {args.name}!')

Example:

Run python greet.py --name Alice to see the greeting.

Step 3: Add Subcommands and Help

Why it matters: Subcommands make your tool more powerful and user-friendly.

What to do:

  1. Add subcommands for different actions:
    python
    parser = argparse.ArgumentParser(description='Todo CLI')
    subparsers = parser.add_subparsers(dest='command')
    
    add_parser = subparsers.add_parser('add', help='Add a todo')
    add_parser.add_argument('task')
    
    list_parser = subparsers.add_parser('list', help='List todos')
    
    args = parser.parse_args()
    if args.command == 'add':
        print(f'Added: {args.task}')
    elif args.command == 'list':
        print('Listing todos...')

Example:

Try python todo.py add "Buy milk" and python todo.py list.

Step 4: Build Advanced CLIs with click

Why it matters: click makes it easy to build complex, beautiful CLIs.

What to do:

  1. Install click:
    bash
    pip install click
  2. Create a click-based CLI:
    python
    import click
    
    @click.group()
    def cli():
        pass
    
    @cli.command()
    def hello():
        click.echo('Hello from click!')
    
    if __name__ == '__main__':
        cli()

Example:

Run python cli.py hello to see the output.

Step 5: Add Colors and Formatting

Why it matters: Colorful output improves usability and fun.

What to do:

  1. Use click's color features:
    python
    @cli.command()
    def warn():
        click.secho('Warning!', fg='yellow', bold=True)

Example:

The warning message appears in yellow and bold.

Step 6: Package and Distribute Your CLI

Why it matters: Packaging lets others install and use your tool easily.

What to do:

  1. Add a setup.py file:
    python
    from setuptools import setup
    
    setup(
      name='mycli',
      py_modules=['cli'],
      install_requires=['click'],
      entry_points='''
        [console_scripts]
        mycli=cli:cli
      ''',
    )
  2. Install your CLI locally:
    bash
    pip install -e .

Example:

Now you can run mycli hello from anywhere.

Step 7: Test and Document Your CLI

Why it matters: Tests and docs ensure your tool is reliable and easy to use.

What to do:

  1. Write tests using pytest:
    python
    def test_hello(runner):
        result = runner.invoke(cli, ['hello'])
        assert 'Hello' in result.output
  2. Add a README.md with usage examples.

Example:

A good README and tests make your project stand out on GitHub.