// Tutorial //

How to Create a CLI with Python Fire on Ubuntu 22.04

Published on September 30, 2022
Default avatar
By Tony Tran
Developer and author at DigitalOcean.
How to Create a CLI with Python Fire on Ubuntu 22.04

Introduction

Python Fire is a Python library that lets you automatically CLIs (command line interfaces) from Python objects. CLIs are programs that take text input from the command line, and can be helpful to your workflow of developing and debugging. This can be useful for those more comfortable in Bash and a command line.

While the traditional method of using argparse from the standard Python library can accomplish the same thing, with Python Fire prototyping and maintenance is greatly improved. If you want that complete control, check out this tutorial on how to use argparse to write command line programs in Python.

In this tutorial you will install Python Fire and use it to create custom CLIs. These CLIs can be created without having to touch the Python source code. Alternatively, for more granular scripts that tie directly into your functions and classes, you will be importing Python Fire and working with it in your code itself.

Prerequisites

Step 1 — Installing Python Fire

Python Fire is hosted on PyPI and is installable from pip. Having followed the prerequisites to install Python 3, you should have a virtual environment created and enabled. If you don’t have it enabled, navigate to your environments directory:

  1. cd environments

Then enable your virtual environment:

  1. source my_env/bin/activate

This ensures that your installation of fire will not affect the global pip installations. Additionally, pip installations at a global level can interact unpredictably with package managers such as apt. With your virtual environment enabled, install fire:

  1. pip install fire

fire can be invoked in multiple ways, including in the command-line with no code additions to your Python programs. You will next explore that method, along with later exploring the conventional usages of Python Fire by adding it to your actual code to enable more granular control.

Step 2 — Creating a CLI from a Program without Code Additions

First, set up your Python file. This can be referred to as a file, a program, or a script, all of which is correct.

To create your new file, use nano or your preferred text editor:

  1. nano example.py

Insert the following Python code in your new file:

example.py
def my_name(name):
  return "My name is {name}".format(name=name)

Save and exit your file. With nano you do this by pressing CTRL+O then CTRL+X.

This is a Python function called my_name and it takes one argument called name. Calling this function with the required variable will insert the name variable into a sentence using Python string formatting. If you were to execute this code in a Python interpreter, with sammy as the variable, it would output “My name is sammy”.

With Python Fire, you can turn this existing Python code into a CLI command and execute this code while inserting a variable, without resorting to writing Python code to invoke it. Enter your new CLI command, using -m to call it as a Python module:

  1. python -m fire example my_name --name=sammy
Output
My name is sammy

Here you are specifying example as the Python program you want to execute, with my_name as the function you want to specifically run. Since my_name is a function that requires one argument called name, you provide the argument using the --name flag.

Without any changes to your Python code, you have built a barebones, working CLI.

Step 3 — Creating a CLI from a Program with fire Imported

The more conventional way of using Python Fire is to import fire into your code. This allows more granular control, and more complex structuring of your code for use within a CLI.

Open your example.py and insert the following code:

example.py
import fire

def my_name(name):
  return "My name is {name}".format(name=name)

if __name__ == '__main__':
  fire.Fire()

There are two notable changes to the original code. fire is imported at the beginning. It is later invoked at the end with a fire.Fire() call, which enables the CLI functionality. This will only happen when the Python program is directly run by the user, and will not run when this file is imported into another Python script. The my_name function itself is unchanged.

Save and exit your file.

Now, you can use your CLI by entering this command:

  1. python example.py my_name sammy
Output
My name is sammy

Because fire is now imported into your Python code at the beginning, you no longer need to call the fire module within your command through python -m. Instead, you can call your CLI through the file directly, and provide arguments for the function name and the variable.

This provides a cleaner CLI experience at the expense of requiring modifications to your actual code. Next, you will create a CLI directly out of a function, instead of the entire Python program.

Step 4 — Creating a CLI from a Function

Instead of exposing all your functions in your program to your CLI, you can choose to create a CLI out of specific functions. Insert the following into your example.py:

example.py
import fire

def my_name(name):
  return "My name is {name}".format(name=name)

def my_full_name(first_name, last_name):
    return "My name is {first_name} {last_name}".format(first_name=first_name, last_name=last_name)

if __name__ == '__main__':
  fire.Fire(my_name)

Save and exit your file.

This time there are two functions. There is the original my_name function, and now a second my_full_name function. The my_full_name function function is a bit different in that it takes two arguments, which Python Fire has the flexibility to allow. It will be used later in this tutorial.

Additionally, when fire.Fire is called at the end, it now takes an argument. In order to specify a function you want to use, you would include it as an argument here. In this example, my_name will be the one you are targeting for your CLI.

Because you specified the function to be used in the CLI, in the command line you only have to provide the program and argument needed to execute the function:

  1. python example.py sammy
Output
My name is sammy

Notice that in the output, only the my_name function is returned, as you specified. The new my_full_name function is untouched.

However, you can expose multiple functions for your CLI. To do this, pass a Python dictionary to the fire.Fire call. Using a dictionary as a key-value data structure allows you to specify multiple functions to your CLI. This dictionary will contain all the functions that you want to use in your CLI. Insert the following into example.py:

example.py
import fire

def my_name(name):
  return "My name is {name}".format(name=name)

def my_full_name(first_name, last_name):
    return "My name is {first_name} {last_name}".format(first_name=first_name, last_name=last_name)

if __name__ == '__main__':
  fire.Fire({
      'my_name': my_name,
      'my_full_name': my_full_name,
  })

Now you can call the first function through your CLI:

  1. python example.py my_name sammy
Output
My name is sammy

Or you can call your second function:

  1. python example.py my_full_name sammy shark
Output
My name is sammy shark

The one change this time is the passing of the dictionary. With the dictionary, you can call either function from your CLI. Next you will be creating a CLI from a Python class, instead of a function.

Step 5 — Creating a CLI from a Class

How you structure your code, whether it be in classes or only functions, is a matter of preference and personal adherence to best practices. Creating a CLI from classes with Python Fire is not drastically different from functions.

To create a class, you’ll be re-structuring your code, placing your functions within it as part of the class. Insert the following into example.py

example.py
import fire

class Namer(object):
    def my_name(self, name):
        return "My name is {name}".format(name=name)

    def my_full_name(self, first_name, last_name):
        return "My name is {first_name} {last_name}".format(first_name=first_name, last_name=last_name)

if __name__ == '__main__':
  fire.Fire(Namer)

Now, despite refactoring your code to use classes, you can use the same command from the previous step to call the first function through your CLI:

  1. python example.py my_name sammy
Output
My name is sammy

Or you can call your second function:

  1. python example.py my_full_name sammy shark
Output
My name is sammy shark

The CLI that is created is functionally identical, using the exact same commands as the previous step. The fire.Fire call is also the same. The only thing that has changed is the restructuring of the code to use classes.

Python Fire adapts to your preferences, allowing you to code in the way you prefer by using classes or regular functions.

Conclusion

In this tutorial, you have installed Python Fire, then explored multiple ways to create your own custom CLIs using Python programs, functions, and classes. For an even deeper dive, check out the official documentation. And for an alternative approach to Python CLI creation, check out the guide on how to use argparse to write command line programs in Python.

If you’ve enjoyed this tutorial and our broader community, consider checking out our DigitalOcean products which can also help you achieve your development goals.

Learn more here


About the authors
Default avatar
Tony Tran

author

Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!