G
GuideDevOps
Lesson 11 of 15

Building CLI Tools

Part of the Python for DevOps tutorial series.

Most DevOps tools are Command Line Interfaces (CLIs). Python's Click library is the industry standard for creating beautiful and intuitive CLIs with minimal code.

1. Getting Started with Click

Click is preferred over the built-in argparse because it uses decorators and handles help pages automatically.

Basic Command

Action:

import click
 
@click.command()
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(name):
    click.echo(f"Hello {name}!")
 
if __name__ == '__main__':
    hello()

Run Command:

python script.py --name DevOps

Result:

Hello DevOps!

2. Options and Arguments

  • Arguments: Required values (e.g., a filename).
  • Options: Optional flags or parameters (e.g., --env or --verbose).

Action:

import click
 
@click.command()
@click.argument('filename')
@click.option('--env', type=click.Choice(['dev', 'prod']), default='dev')
@click.option('--force', is_flag=True, help='Force the deployment')
def deploy(filename, env, force):
    click.echo(f"Deploying {filename} to {env}...")
    if force:
        click.echo("Force mode enabled!")
 
if __name__ == '__main__':
    deploy()

Run Command:

python deploy.py config.yaml --env prod --force

Result:

Deploying config.yaml to prod...
Force mode enabled!

3. Multi-Command CLIs (Groups)

For complex tools (like kubectl or git), you can group commands together.

Action:

import click
 
@click.group()
def cli():
    pass
 
@cli.command()
def start():
    click.echo("Starting services...")
 
@cli.command()
def stop():
    click.echo("Stopping services...")
 
if __name__ == '__main__':
    cli()

Run Command:

python mytool.py start

Result:

Starting services...

4. User Interaction: Prompts & Confirmation

DevOps scripts often need safety checks before destructive actions.

Action:

import click
 
@click.command()
def delete_db():
    if click.confirm('Are you SURE you want to delete the production database?'):
        click.echo('Deleting database...')
    else:
        click.echo('Operation cancelled.')
 
if __name__ == '__main__':
    delete_db()

Run Command:

python script.py

Result (Interactive):

Are you SURE you want to delete the production database? [y/N]: n
Operation cancelled.

Summary

  • Use click instead of argparse for modern tools.
  • Use @click.option for flags and settings.
  • Use @click.argument for required inputs.
  • Always include help= strings for your users.
  • Use click.confirm before destructive actions.