以下の記事を参考に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
↑ これしか見つからなかったので、とりあえずこれを参考にしました。
markdownじゃないので、ちょっと見にくい。。。(他に正式なドキュメントがあるのかも?)
シンプルだけど、機能は少なめな雰囲気。
click
機能も豊富にありそう。設定可能な項目が多い分、実装はほかよりも少し手間がかかりそうだけど、かゆいところに手が届きそうなのがぐっとくる。ドキュメントも充実。
fire
実装が一番楽そう。機能もそこそこ充実。機能も豊富で、ネスティングに加えて、チェインコールやプロパティの表示にも対応。簡単実装で機能もそこそこ充実してるけど、オプションの解説設定ができなさそうなのが、けっこうつらい。ヘルプ表示も縦長で、ちょっと見ずらい。
まとめ
かゆい所に手が届くclickと簡単実装と機能のバランスがいいfireで迷ったあげく、両方かな(笑)という結論に至りました。
とりあえずfireでコマンド化して、ヘルプを強化したくなったらclickに切り替えみたいな感じで、使ってみようと思います。
切り替えを想定して関数ベースで実装する事だけ気を付けて、しばらく試してみようと思います。
※ ドキュメントなど、ざっくり見ただけなので、間違ってるところがあったら、指摘コメントなど頂けると助かります。
おまけ: ソースコード(比較用環境付き)
使用したコードは以下参照。比較用環境付き