Leverage Click to Build CLI interface for a Program

Leverage Click to Build CLI interface for a Program

Here in this article we will try to leverage Python click library to build a CLI tool or interface for a python application.

Test Environment

  • Fedora 42 server
  • Python v3.13.13

What is Python Click

Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It’s the “Command Line Interface Creation Kit”. It’s highly configurable but comes with sensible defaults out of the box.

Any CLI tool or interface that you may have used or came across, provides us with a useful help information consisting of the Options, Arguments and Commands that can be passed to the program. Take an example of uv package manager CLI tool and its “–help” output as shown below.

admin@fedser:click$ uv --help
An extremely fast Python package manager.

Usage: uv [OPTIONS] <COMMAND>

Commands:
  auth     Manage authentication
  run      Run a command or script
  init     Create a new project
  add      Add dependencies to the project
  remove   Remove dependencies from the project
  version  Read or update the project's version
  sync     Update the project's environment
  lock     Update the project's lockfile
  export   Export the project's lockfile to an alternate format
  tree     Display the project's dependency tree
  format   Format Python code in the project
  audit    Audit the project's dependencies
  tool     Run and install commands provided by Python packages
  python   Manage Python versions and installations
  pip      Manage Python packages with a pip-compatible interface
  venv     Create a virtual environment
  build    Build Python packages into source distributions and wheels
  publish  Upload distributions to an index
  cache    Manage uv's cache
  self     Manage the uv executable
  help     Display documentation for a command

Cache options:
  -n, --no-cache               Avoid reading from or writing to the cache, instead using a temporary
                               directory for the duration of the operation [env: UV_NO_CACHE=]
      --cache-dir <CACHE_DIR>  Path to the cache directory [env: UV_CACHE_DIR=]

Python options:
      --managed-python       Require use of uv-managed Python versions [env: UV_MANAGED_PYTHON=]
      --no-managed-python    Disable use of uv-managed Python versions [env: UV_NO_MANAGED_PYTHON=]
      --no-python-downloads  Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"]

Click is based on declaring commands through decorators. A function becomes a Click command line tool by decorating it through command(). So decorator converts the function into a Command which then can be invoked.

If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.

Procedure

Step1: Ensure UV package manager installed

Here we are going to use “UV” package manager to build and install our pyython project which we will be converting into a CLI tool.

admin@fedser:click$ sudo dnf install uv

Step2: Initialize a UV project

Let’s initialize a UV project with a package named “greet_cli” and switch into that created folder.

admin@fedser:click$ mkdir greet-cli-app
admin@fedser:click$ cd greet-cli-app/
admin@fedser:greet-cli-app$ uv init --package greet_cli
Initialized project `greet-cli` at `/home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-app/greet_cli`

Step3: Add Click dependency

Here we are going to add the “Click” dependency which we will use to build the CLI interface for our python applicaiton.

admin@fedser:greet_cli$ uv add click --system-certs
Using CPython 3.13.13 interpreter at: /usr/bin/python3.13
Creating virtual environment at: .venv
Resolved 2 packages in 15ms
      Built greet-cli @ file:///home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-
Prepared 1 package in 7ms
Installed 2 packages in 1ms
 + click==8.5.0
 + greet-cli==0.1.0 (from file:///home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-app/greet_cli)

Step4: Update python script

Now let’s create a “greet.py” script which consist of two function “hello()” and “bye()” which are decorated using the @click.command(). This converts our function into a command which can be invoked using the CLI tool.

Here we are grouping our commands into a group name “cli” which when invoked activates both of our commands.

admin@fedser:greet_cli$ cat src/greet_cli/greet.py 
import click

@click.group()
def cli():
    pass

@click.command()
@click.option('--name', default='World', help='The person to greet.')
def hello(name):
    print('Hello ' + name)

@click.command()
@click.option('--name', default='World', help='Send off a person')
def bye(name):
    print('Good Bye ' + name)

cli.add_command(hello)
cli.add_command(bye)

if __name__ == '__main__':
    cli()

Once the script is updated, we need to configure the entrypoint for our script execution which is going to be “greet_cli.greet:cli”.

admin@fedser:greet_cli$ cat pyproject.toml 
[project]
name = "greet-cli"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
    { name = "novicejava1", email = "novicejava1@gmail.com" }
]
requires-python = ">=3.13"
dependencies = [
    "click>=8.5.0",
]

[project.scripts]
greet-cli = "greet_cli.greet:cli"

[build-system]
requires = ["uv_build>=0.11.11,<0.12.0"]
build-backend = "uv_build"

Step5: Run Python CLI tool

Let’s now try to run the “greet.py” script without actually building the package and see it in action. As we can see it provided a nice “help” output on how we can use the script.

admin@fedser:greet_cli$ uv run src/greet_cli/greet.py 
Usage: greet.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  bye
  hello

Now let’s run the script with each command and the options that we can pass to those commands.

admin@fedser:greet_cli$ uv run src/greet_cli/greet.py hello --name Click
Hello Click
admin@fedser:greet_cli$ uv run src/greet_cli/greet.py bye --name Click
Good Bye Click

Step6: Build Python Package

Once we are satisfied that our python cli interface is working as expected we can build the package.

admin@fedser:greet_cli$ uv build
Building source distribution (uv build backend)...
Building wheel from source distribution (uv build backend)...
Successfully built dist/greet_cli-0.1.0.tar.gz
Successfully built dist/greet_cli-0.1.0-py3-none-any.whl

Step7: Install Python Package

Here we will install the python package that was built. Its going to install the package into the uv virtual environment.

admin@fedser:greet_cli$ uv pip install --editable . --system-certs
Resolved 2 packages in 1ms
      Built greet-cli @ file:///home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-
Prepared 1 package in 5ms
Uninstalled 1 package in 0.53ms
Installed 1 package in 4ms
 ~ greet-cli==0.1.0 (from file:///home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-app/greet_cli)

We can list the installed package within the uv environment by running the below.

admin@fedser:greet_cli$ uv pip list
Package   Version Editable project location
--------- ------- ---------------------------------------------------------------------------------------
click     8.5.0
greet-cli 0.1.0   /home/admin/middleware/stack/vscodeprojects/pythonscratch/click/greet-cli-app/greet_cli

Step8: Run with Installed Binary

Now let’s try to run the executable which we named as “greet-cli” in the “[project.scripts]” section of the toml file along with the commands and options as shown below.

admin@fedser:greet_cli$ uv run greet-cli hello --name Click
Hello Click
admin@fedser:greet_cli$ uv run greet-cli bye --name Click
Good Bye Click

Hope you enjoyed reading this article. Thank you..