7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-09-08

以下の記事を参考に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

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?