Edited at

CLI自動生成パッケージ baker, click, fire を比較 [python]

以下の記事を参考にbaker, click, fireを比較。

コマンドラインツールを自動生成できるPython Fireと他のライブラリ比べてみた


比較に利用する、コマンド定義コード

※ ほぼほぼ、上述リンクのコピペ。一部、比較用に調整。


baker

import requests

import json
import baker

@baker.command(params={"product_code": "'BTC_JPY or BTC_ETH", "is_json": "return json"})
def bitflyer_getticker(product_code='BTC_JPY', is_json=False):
"""bitflyer api getticker
"""

end_point = "https://api.bitflyer.jp/v1/getticker"
r = requests.get(end_point, params={'product_code': product_code})
r_json = json.loads(r.text)
if product_code == None:
print('BTC_JPY')
else:
print(product_code)

if is_json:
print(r_json)
else:
print("bid:{}".format(r_json['best_bid']))
print("ask{}".format(r_json['best_ask']))

baker.run()

シンプルで、設定が簡単そう。引数がそのままオプションになるみたいなので、短いオプションにしたい場合は、product_code=pみたいな感じで関数内で置き換えが必要になりそう。


click

import requests

import json
import click

@click.group()
def cli():
pass

@click.command()
@click.option('--product_code', '-p', default='BTC_JPY', help=u'BTC_JPY or BTC_ETH')
@click.option('--is_json/--no-is_json', default=False, help=u"return json")
def bitflyer_getticker(product_code='BTC_JPY', is_json=False):
end_point = "https://api.bitflyer.jp/v1/getticker"
r = requests.get(end_point, params={'product_code': product_code})
r_json = json.loads(r.text)
if product_code == None:
print('BTC_JPY')
else:
print(product_code)

if is_json:
print(r_json)
else:
print("bid:{}".format(r_json['best_bid']))
print("ask{}".format(r_json['best_ask']))

cli.add_command(bitflyer_getticker)

if __name__ == "__main__":
cli()

ネスティングコマンドが試したかったので、参考にした記事から少し調整。細かい設定が可能そうで、短縮版のオプションの定義も簡単そう。


fire

import requests

import json
import fire

class Bitflyer():
def __init__(self, end_point="https://api.bitflyer.jp/v1/getticker"):
self.end_point = end_point

def getticker(self, product_code='BTC_JPY', is_json=False):
r = requests.get(self.end_point, params={'product_code': product_code})
r_json = json.loads(r.text)
if product_code == None:
print('BTC_JPY')
else:
print(product_code)

if is_json:
print(r_json)
else:
print("bid:{}".format(r_json['best_bid']))
print("ask{}".format(r_json['best_ask']))

if __name__ == "__main__":
fire.Fire(Bitflyer)

簡単実装。fireパッケージをimportして、最後にfire.Fire()とするだけでOK。クラスにも対応。クラスの場合はfire.Fire(クラス名)で実装。機能も豊富そうだけど、オプションの解説を設定できなさそうなのが難点。


ヘルプ比較


baker

$ python baker_trial.py --help

Usage: baker_trial.py COMMAND <options>

Available commands:
bitflyer_getticker bitflyer api getticker

Use 'baker_trial.py <command> --help' for individual command help.

短くシンプルで見やすい。


click

$ python click_trial.py --help

Usage: click_trial.py [OPTIONS] COMMAND [ARGS]...

Options:
--help Show this message and exit.

Commands:
bitflyer-getticker

baker同様、短くシンプルで見やすい。


fire


ヘルプオプションありの場合

$ python fire_trial.py -- --help

NAME
fire_trial.py

SYNOPSIS
fire_trial.py <flags>

FLAGS
--end_point=END_POINT


ヘルプオプションなしの場合

$ python fire_trial.py

NAME
fire_trial.py

SYNOPSIS
fire_trial.py - COMMAND | VALUE

COMMANDS
COMMAND is one of the following:

getticker

VALUES
VALUE is one of the following:

end_point

ヘルプ無しでpython fire_trial.pyと入力するとコマンドリストが表示されるのに、コマンドリストヘルプだとなぜか寂しい。縦に長く、表示が切れるとパッと見でわかりにくそう。オプション解説がないのも、ちょっとつらい。


個別コマンドヘルプ比較


baker

$ python baker_trial.py bitflyer_getticker --help

Usage: baker_trial.py bitflyer_getticker [<product_code>] [<is_json>]

bitflyer api getticker

Options:

--product_code 'BTC_JPY or BTC_ETH
--is_json return json

シンプル。オプションの解説があるのは、やっぱり落ち着く。


click

$ python click_trial.py bitflyer-getticker --help

Usage: click_trial.py bitflyer-getticker [OPTIONS]

Options:
-p, --product_code TEXT BTC_JPY or BTC_ETH
--is_json / --no-is_json return json
--help Show this message and exit.

シンプル。短縮版オプションがつかえるのが便利そう。


fire

$ python fire_trial.py getticker -- --help

NAME
fire_trial.py getticker

SYNOPSIS
fire_trial.py getticker <flags>

FLAGS
--product_code=PRODUCT_CODE
--is_json=IS_JSON

少し縦長。オプション解説がないのも少し寂しい


個別まとめ(ドキュメントリンク付き)


baker

README.txt

↑ これしか見つからなかったので、とりあえずこれを参考にしました。

markdownじゃないので、ちょっと見にくい。。。(他に正式なドキュメントがあるのかも?)

シンプルだけど、機能は少なめな雰囲気。


click

Documentation

機能も豊富にありそう。設定可能な項目が多い分、実装はほかよりも少し手間がかかりそうだけど、かゆいところに手が届きそうなのがぐっとくる。ドキュメントも充実。


fire

The Python Fire Guide

実装が一番楽そう。機能もそこそこ充実。機能も豊富で、ネスティングに加えて、チェインコールやプロパティの表示にも対応。簡単実装で機能もそこそこ充実してるけど、オプションの解説設定ができなさそうなのが、けっこうつらい。ヘルプ表示も縦長で、ちょっと見ずらい。


まとめ

かゆい所に手が届くclickと簡単実装と機能のバランスがいいfireで迷ったあげく、両方かな(笑)という結論に至りました。

とりあえずfireでコマンド化して、ヘルプを強化したくなったらclickに切り替えみたいな感じで、使ってみようと思います。

切り替えを想定して関数ベースで実装する事だけ気を付けて、しばらく試してみようと思います。

※ ドキュメントなど、ざっくり見ただけなので、間違ってるところがあったら、指摘コメントなど頂けると助かります。


おまけ: ソースコード(比較用環境付き)

使用したコードは以下参照。比較用環境付き

mm0202/python-cli-generation-packages