Python Fire

A library by Google that automatically generates CLIs from any Python object. Create CLIs with minimal code.

pythoncligoogleautomatic

GitHub Overview

google/python-fire

Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.

Stars27,770
Watchers366
Forks1,456
Created:February 21, 2017
Language:Python
License:Other

Topics

clipython

Star History

google/python-fire Star History
Data as of: 7/25/2025, 02:00 AM

Framework

Python Fire

Overview

Python Fire is a Python library developed by Google that automatically generates command-line interfaces (CLI) from any Python object. It takes an innovative approach where a single fire.Fire() call can transform functions, classes, modules, dictionaries, and more into CLIs. Version 0.7.0 was released in October 2024, dropping Python 2 support and adding Python 3.13 compatibility.

Details

Python Fire is designed based on a "zero configuration" philosophy, eliminating the need for explicit argument definitions, subcommand setup, or help text creation. Developers simply write regular Python code, and Fire automatically generates the CLI.

Latest Updates (2024)

2024 has been a significant year for Python Fire:

  • v0.7.0 (October 1, 2024): Dropped Python 2 support, making it Python 3 only. Added Python 3.13 support and improved CI/CD processes with dependabot integration.
  • v0.6.0 (March 11, 2024): The last version supporting Python 2. Improved auto-generated help text to show short arguments (e.g., -a) when appropriate, and default values are now shown in help for keyword-only arguments.

The project remains actively maintained by Google with over 27,000 stars and 1,400+ forks on GitHub, demonstrating its stability and community adoption.

Key Features

  • Automatic CLI Generation: Automatically creates CLIs from functions, classes, objects, modules, dictionaries, and lists
  • Type Inference: Automatically converts command-line arguments to appropriate Python types (numbers, strings, tuples, lists, dictionaries, booleans)
  • Hierarchical Command Processing: Natural navigation through object hierarchies with chainable method calls and property access
  • Interactive Mode: Built-in REPL provided with the --interactive flag
  • Auto-completion: Tab completion support for Bash, Fish, and Zsh
  • Debug Support: Execution trace display with the --trace flag
  • Flexible Execution: Turn any module into a CLI without code changes using python -m fire

Pros and Cons

Pros

  • Create CLIs with minimal code
  • Instantly turn existing Python code into CLIs
  • Gentle learning curve (just write regular Python code)
  • Easy debugging and code exploration
  • Automatic argument handling through type inference
  • Stable support from Google

Cons

  • Limited control over fine-grained CLI behavior
  • Not suitable for complex argument validation
  • Limited customization of auto-generated help messages
  • Structural limitations for large-scale CLI applications
  • Python 2 support ended (v0.7.0+)

Key Links

Code Examples

Basic Function CLI

import fire

def hello(name="World"):
    return f"Hello {name}!"

if __name__ == '__main__':
    fire.Fire(hello)
# Usage examples
python hello.py                  # Hello World!
python hello.py --name=Alice     # Hello Alice!
python hello.py --help           # Shows usage information

Class CLI

import fire

class Calculator:
    """A simple calculator class"""
    
    def add(self, x, y):
        return x + y
    
    def multiply(self, x, y):
        return x * y

if __name__ == '__main__':
    fire.Fire(Calculator)
# Usage examples
python calculator.py add 10 20           # 30
python calculator.py multiply --x=5 --y=3  # 15

Exposing Multiple Commands

import fire

def add(x, y):
    return x + y

def multiply(x, y):
    return x * y

def power(x, y=2):
    return x ** y

if __name__ == '__main__':
    fire.Fire()  # Exposes all functions
# Usage examples
python math_tools.py add 10 20          # 30
python math_tools.py multiply 5 3       # 15
python math_tools.py power 2 8          # 256

Advanced Features Example

import fire

class Pipeline:
    def __init__(self):
        self.ingestion = IngestionStage()
        self.digestion = DigestionStage()
    
    def run(self):
        ingestion_output = self.ingestion.run()
        digestion_output = self.digestion.run()
        return [ingestion_output, digestion_output]

class IngestionStage:
    def run(self):
        return 'Ingesting! Nom nom nom...'

class DigestionStage:
    def run(self, volume=1):
        return ' '.join(['Burp!'] * volume)
    
    def status(self):
        return 'Satiated.'

if __name__ == '__main__':
    fire.Fire(Pipeline)
# Usage examples
python pipeline.py run                              # Run entire pipeline
python pipeline.py ingestion run                    # Run specific stage
python pipeline.py digestion run --volume=3         # Run with parameters
python pipeline.py digestion status                 # Check status

Method Chaining Example

import fire

class BinaryCanvas:
    """A canvas for creating binary art"""
    
    def __init__(self, size=10):
        self.pixels = [[0] * size for _ in range(size)]
        self._size = size
        self._row = 0
        self._col = 0
    
    def __str__(self):
        return '\n'.join(' '.join(str(pixel) for pixel in row) 
                        for row in self.pixels)
    
    def move(self, row, col):
        self._row = row % self._size
        self._col = col % self._size
        return self
    
    def on(self):
        self.pixels[self._row][self._col] = 1
        return self
    
    def show(self):
        print(self)
        return self

if __name__ == '__main__':
    fire.Fire(BinaryCanvas)
# Method chaining example
python canvas.py move 3 3 on move 3 6 on show

Debug and Interactive Mode

import fire

class DataProcessor:
    def __init__(self, data_path="data.csv"):
        self.data_path = data_path
        self.data = None
    
    def load(self):
        print(f"Loading data from {self.data_path}")
        # Data loading logic
        self.data = [1, 2, 3, 4, 5]
        return self
    
    def process(self, operation="sum"):
        if operation == "sum":
            return sum(self.data)
        elif operation == "mean":
            return sum(self.data) / len(self.data)

if __name__ == '__main__':
    fire.Fire(DataProcessor)
# Debug mode
python processor.py --trace load process

# Interactive mode
python processor.py --interactive
# REPL starts, allowing object exploration