Creating Python CLI tools
Tags: python, cli, terminal
Published: 2021-10-29 04:00:14

---
title: Creating Python CLI tools
published: true
description: Using a Python CLI template to create CLI tooling
tags: python, cli, terminal
//cover_image: https://direct_url_to_image.jpg
---
A link to the [GitHub repo](https://github.com/hunttom/python_cli_skeleton)

An example using the CLI Skeleton can be found [here](https://github.com/hunttom/groundhogs_day)

## Prerequisites:
1. Python 3.6+

# Introduction:
Initially, I wanted to create a Python CLI tool to help automate certain aspects of my day. This tooling was inspired by me trying to use Python files when I needed to run a task such as log into a website, push code, or check the security configurations of my cloud projects. These repeated tasks were boring and distracted me from more important tasks.

After reading through multiple blog posts and GitHub repositories, I found that there wasn't an clean, easy, and updated way to write a quick Python function. I wanted these scripts to be able to be called from the command line without too much effort or overhead with refactoring my code. So I decided to build a repeatable pattern that others could use.

# The Solution:
In the theme of October, I have created a "cli_skeleton" which will allow you to create and automate such tasks.

### Project Layout:

```bash
.
├── cli_skeleton
│   ├── core
│   │   └── exceptions.py
│   ├── functions
│   │   └── test_function.py
│   ├── __init__.py
│   └── __main__.py
├── LICENSE
├── Makefile
├── README.md
└── setup.py
```

### Starting top to bottom:
#### Core Directory:
Add any actions which are universal or shared actions, such as error handling that you would want to across all functions or functionality.

#### Functions:
This directory holds your Python functions. You can have multiple functions in this directory and reference them in the `__main__.py` file. 

A basic function layout is as follows:

```python
from cli_skeleton.core.exceptions import CLISkeletonExceptions 
# Importing all the core functions, in this instance, exceptions and error handling.


def test_print(test):
"""
The main function I want to run
"""
    try:
        print(test)
    except Exception as err:
        raise CLISkeletonExceptions(str(err))
    else:
        print("Successfully ran the CLI test script")
```

#### __main__.py
This Python file is the main entry point to the CLI tool. You add your logic accordingly. In the function I created, I used [argparse](https://docs.python.org/3/library/argparse.html) to allow me to put arguments into the CLI tool.

```python
from cli_skeleton.functions.test_function import test_print
# Import the functions you want to use

def main():
"""
For this example CLI script, the logic evaluates to 'True' thus running the function 'test_print' passing in 'Hi Dev.to!'
"""
    if True:  # Logic for functions
        test_print("Hi Dev.to!") # The function imported from line 1.
    
if __name__ == '__main__':
    main()
```

#### Makefile
I've included a Makefile to help various tasks such as:
1. `make` installs the tool locally
2. `make uninstall` uninstalls the tool locally
3. `make venv` creates a Python venv.
4. `make test` installs and tests the tool based on a set of CLI commands. For the example I am running `cli_skeleton` as the test
5. `make clean` removes the venv and removes all .pyc files.

Feel free to study up on Makefiles and edit to your hearts content.

#### README
I've included a sample README

#### setup.py
This file sets all the metadata for your Python CLI tool. 
Update accordingly.

## Sharing and installing on different machines:
1. You can use GitHub to share/install your Python tool, run `pip3 install git+https://github.com/<USER>/<REPO_NAME>@<BRANCH NAME>` for example: `pip3 install git+https://github.com/hunttom/cli_skeleton@main`

# Conclusion:
In this post, I have covered the layout to a Python CLI tool and how to modify the files and install. I hope you can use this layout to create your own Python CLI tools! Best of luck and happy coding!

## Additional reading/resources to help:
1. [About Argparse](https://docs.python.org/3/library/argparse.html)
2. [About Makefiles](https://dev.to/matthewepler/using-makefiles-to-automate-workflows-acd)
3. [About setup.py](https://dev.to/niklastiede/distribute-a-python-app-via-setup-py-file-4boh)