For years, I’ve been writing Python scripts, everything from small utilities to automate repetitive work, for testing APIs, or to process data. And every time I wanted to make one of them accessible from the terminal, I ran into the same annoyance: argument parsing.
Sure, Python’s built-in argparse
works perfectly fine. But it’s verbose. Every time, I’d find myself writing a dozen lines of boilerplate just to pass a couple of arguments. If I wanted subcommands, things got messy fast.
So I did what every Python developer does: I started looking for “a better way.”
That’s when I stumbled across a small but surprisingly powerful library from Google called Fire.
And it completely changed the way I build CLIs.
What Is Google Fire?
Google Fire is a Python library that automatically generates command-line interfaces (CLIs) from any Python object, functions, classes, dictionaries, or even whole modules.
You don’t need to define command-line arguments manually.
You don’t need to handle type conversions.
You don’t even need to write a main()
function.
You just call fire.Fire()
, and your code instantly becomes a CLI.
Installation
Installing Fire is as simple as it gets:
pip install fire
No dependencies, no setup scripts, no configuration.
How Fire Works
Fire works by introspecting your Python objects.
When you call fire.Fire()
, it examines the function or class you pass in and exposes its attributes and methods as CLI commands.
For example:
- Each method of a class becomes a subcommand.
- Each parameter becomes a CLI argument.
- Keyword arguments (
def func(x=5)
) become optional flags.
So if you define:
def greet(name="world", excited=False):
msg = f"Hello, {name}!"
return msg.upper() if excited else msg
You can run it as:
python greet.py John
python greet.py John --excited True
and get:
Hello, John!
HELLO, JOHN!
Fire automatically detects the types of arguments and converts them when possible. It even understands nested structures, if your function returns a dictionary or an object, Fire lets you explore it interactively right from the command line.
Let's see the full script from the previous snippets:
import fire
def greet(name="world", excited=False):
msg = f"Hello, {name}!"
return msg.upper() if excited else msg
if __name__ == "__main__":
fire.Fire(greet)
If you enjoy practical Python content like this, check out my free developer resource pack here.
A More Realistic Example: Building a Quick Calculator
After that first “aha!” moment, I wanted to see how far I could push it.
What if I turned a class into a CLI?
import fire
class Calculator:
"""A simple calculator."""
def add(self, x, y):
"""Add two numbers."""
return x + y
def mul(self, x, y):
"""Multiply two numbers."""
return x * y
if __name__ == "__main__":
fire.Fire(Calculator)
Now, running commands like:
python calc.py add 2 3
outputs:
5
and
python calc.py mul 4 5
outputs:
20
Need help? Just type:
python calc.py --help
And Fire will auto-generate help documentation for you, including all methods and arguments:
INFO: Showing help with the command 'calc.py -- --help'.
NAME
calc.py - A simple calculator.
SYNOPSIS
calc.py -
DESCRIPTION
A simple calculator.
When to Use Fire - and When Not To
Fire is brilliant for:
- Prototyping and internal tools
- Debugging utilities
- Small automation scripts
- Exposing classes or APIs interactively
But it’s not ideal for production-grade CLIs where you need:
- Custom argument validation
- Rich UI elements (spinners, colors, etc.)
- Nested command hierarchies
- Compatibility with shell autocompletion
For that, you’ll probably want something like Click or Typer.
That said, Fire and Typer complement each other well: I found myself using Fire during early prototyping and switch to Typer once I need more structure.
My Takeaway
Fire reminded me why I love Python in the first place, it turns everyday code into something more powerful without getting in the way.
When I’m sketching ideas, writing quick tools, or testing APIs, Fire lets me focus on the logic, not the interface.
And the best part? You can remove it anytime. There’s no lock-in.
I’ve come to end many scripts with this familiar pattern:
if __name__ == "__main__":
import fire
fire.Fire()
It’s almost a reflex now, like adding print()
statements to debug, but cleaner.
Fire just makes your scripts feel simpler and alive.
If you’ve ever wanted your Python scripts to instantly “speak CLI,” give Fire a try.
It takes seconds to set up and might save you hours of boilerplate.
Follow me on Twitter: https://twitter.com/DevAsService
Follow me on Instagram: https://www.instagram.com/devasservice/
Follow me on TikTok: https://www.tiktok.com/@devasservice
Follow me on YouTube: https://www.youtube.com/@DevAsService
Top comments (0)