Python Fire
Googleが開発した、任意のPythonオブジェクトから自動的にCLIを生成するライブラリ。最小限のコードでCLIを作成できます。
GitHub概要
google/python-fire
Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.
スター27,770
ウォッチ366
フォーク1,456
作成日:2017年2月21日
言語:Python
ライセンス:Other
トピックス
clipython
スター履歴
データ取得日時: 2025/7/25 02:00
フレームワーク
Python Fire
概要
Python FireはGoogleが開発したPythonライブラリで、任意のPythonオブジェクトから自動的にコマンドラインインターフェース(CLI)を生成します。単一のfire.Fire()
呼び出しだけで、関数、クラス、モジュール、辞書などをCLIに変換できる、革新的なアプローチを採用しています。2024年10月にバージョン0.7.0がリリースされ、Python 2サポートが終了し、Python 3.13への対応が追加されました。
詳細
Python Fireは「ゼロコンフィギュレーション」の哲学に基づいて設計されており、明示的な引数定義、サブコマンド設定、ヘルプテキストの作成が不要です。開発者は通常のPythonコードを書くだけで、Fireが自動的にCLIを生成します。
最新動向(2024年)
2024年はPython Fireにとって重要な年となりました:
- v0.7.0(2024年10月1日): Python 2サポートを終了し、Python 3専用となりました。Python 3.13への対応が追加され、CI/CDプロセスの改善とdependabotサポートが導入されました。
- v0.6.0(2024年3月11日): Python 2をサポートする最後のバージョン。自動生成されるヘルプテキストが改善され、適切な場合に短い引数(例:-a)が表示されるようになりました。キーワード専用引数のデフォルト値がヘルプに表示されるようになりました。
Googleによる継続的なメンテナンスにより、GitHubでは27,000以上のスターと1,400以上のフォークを獲得している安定したプロジェクトです。
主な特徴
- 自動CLI生成: 関数、クラス、オブジェクト、モジュール、辞書、リストから自動的にCLIを作成
- 型推論: コマンドライン引数を適切なPython型(数値、文字列、タプル、リスト、辞書、ブール値)に自動変換
- 階層的コマンド処理: オブジェクト階層を自然にナビゲートし、メソッド呼び出しやプロパティアクセスを連鎖可能
- インタラクティブモード:
--interactive
フラグで組み込みREPLを提供 - 自動補完: Bash、Fish、Zshでのタブ補完をサポート
- デバッグ支援:
--trace
フラグで実行トレースを表示 - 柔軟な実行: コードを変更せずに
python -m fire
で任意のモジュールをCLI化
メリット・デメリット
メリット
- 最小限のコードでCLIを作成可能
- 既存のPythonコードを即座にCLI化
- 学習曲線が緩やか(通常のPythonコードを書くだけ)
- デバッグとコード探索が容易
- 型推論による自動的な引数処理
- Googleによる安定したサポート
デメリット
- 細かいCLI動作の制御が困難
- 複雑な引数検証には不向き
- 自動生成されるヘルプメッセージのカスタマイズが限定的
- 大規模なCLIアプリケーションには構造的な制限
- Python 2サポートが終了(v0.7.0以降)
主要リンク
書き方の例
基本的な関数のCLI化
import fire
def hello(name="World"):
return f"Hello {name}!"
if __name__ == '__main__':
fire.Fire(hello)
# 使用例
python hello.py # Hello World!
python hello.py --name=Alice # Hello Alice!
python hello.py --help # ヘルプメッセージを表示
クラスのCLI化
import fire
class Calculator:
"""シンプルな計算機クラス"""
def add(self, x, y):
return x + y
def multiply(self, x, y):
return x * y
if __name__ == '__main__':
fire.Fire(Calculator)
# 使用例
python calculator.py add 10 20 # 30
python calculator.py multiply --x=5 --y=3 # 15
複数コマンドの公開
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() # すべての関数を公開
# 使用例
python math_tools.py add 10 20 # 30
python math_tools.py multiply 5 3 # 15
python math_tools.py power 2 8 # 256
高度な機能の例
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)
# 使用例
python pipeline.py run # 全体を実行
python pipeline.py ingestion run # 特定ステージを実行
python pipeline.py digestion run --volume=3 # パラメータ付き実行
python pipeline.py digestion status # ステータス確認
メソッドチェーンの例
import fire
class BinaryCanvas:
"""バイナリアートを作成するキャンバス"""
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)
# メソッドチェーンの使用例
python canvas.py move 3 3 on move 3 6 on show
デバッグとインタラクティブモード
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}")
# データ読み込み処理
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)
# デバッグモード
python processor.py --trace load process
# インタラクティブモード
python processor.py --interactive
# REPLが起動し、オブジェクトを探索可能