clickでcliをお手軽につくるぅぅぅ
TRANSCRIPT
Click で CLI をお手軽につくるぅぅぅぅ
@fmkz___
自己紹介
• @fmkz___–某製薬企業の研究職–静岡デベロッパーズの「プログラミング
Haskell 読書会」からコミュニティに参加し始める (2011 くらい )
–最近なぜが jQuery 書いてます(謎)
– 年末に転職しました
そんなある日、心機一転ウェブサービスでも作るかと
pip install flask
flask コマンド出来てた…
• python app.py じゃなくて flask run• click 使って書かれてた
$ export FLASK_APP=app.py$ export FLASK_DEBUG=1$ flask run host=0.0.0.0
click ?
• Flask の作者 Armin Ronacher によるCLI 作成ツール
• http://click.pocoo.org/5/
click 使いやすい
• 今まで optparse とか argparse を使っていたけど click に乗り換えた
• argparse とか覚えにくかったimport argparse
parser = argparse.ArgumentParser(description='Process some integers.')parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator')parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)')
args = parser.parse_args()print(args.accumulate(args.integers))
click だと import して @ で包むだけ
import click
@click.command()@click.argument("name")@click.option("--shiz", is_flag=True)def cli(name, shiz): gleet = " うみゃ〜ら " if shiz else "Hello" click.echo("{} {}".format(gleet, name))
if __name__ == '__main__': cli()
help ももちろん
$ python sample.py --helpUsage: sample.py [OPTIONS] NAME
Options: --shiz --help Show this message and exit.
サブコマンド作るのが簡単
• サブコマンド?• git add とか git status みたいなやつ• git init --bare みたいにサブコマンドが
オプションを取る
というわけで今日は click を使ってぬか床エミュレーターを作ってみましょう
私とぬか漬け
• 近所に美味しいぬか漬けが売ってない…
• ならば作ってしまえと去年のゴールデンウィークに突然ぬか床をこしらえ始めた
• かき混ぜるのは手間だけど、ゴーヤとか小松菜とかゆで卵とか色々漬けられて楽しい
コマンド名は nucca• まずは init できないとね
repo_name = ".nucca"
@click.group()def cli(): pass
@cli.command()def init(): os.mkdir(repo_name) nucca = {} nucca["started"] = datetime.now() joblib.dump(nucca, os.path.join(repo_name, "default")) click.echo("Created an empty Nucca repository")
init してみましょう$ python nucca.py --helpUsage: nucca.py [OPTIONS] COMMAND [ARGS]...
Options: --help Show this message and exit.
Commands: init
$ python nucca.py initCreated an empty Nucca repository
add 実装
• add できるように• argument と option の二種類あります
@cli.command(help="Add materials to the Nucca-docco")@click.argument("material")def add(material): nucca = joblib.load(os.path.join(repo_name, "default")) nucca["materials"].append(material) joblib.dump(nucca, os.path.join(repo_name, "default")) click.echo("Add {}".format(material))
めんどくさがらずにクラスにしてけばよかった…
いまどうなってんの?
• status できるように@cli.command(help="Show the Nucca-docco status")def status(): nucca = load() tdelta = datetime.now() - nucca["started"] acid_option = 0 if "biofermin" in nucca["materials"]: acid_option += 1000 if "nukamiso-karashi" in nucca["materials"]: acid_option -= 500
acidity = 100 * (tdelta.seconds + acid_option) / 3600.0 click.echo(" 乳酸菌 {}".format(acidity)) click.echo(" 中に入っているもの {}".format(", ".join(nucca["materials"])))
産地のトレース
• [email protected](help="Trace materials")@click.argument("material")def trace(material): if material == "cucumber": click.launch("https://cucumber.io/") elif material == "letuce": click.launch("http://lettuce.it/tutorial/simple.html") else: click.echo("unknown")
かき混ぜる機能忘れてた
• mix• プログレスバーも出せます
@cli.command(help="Mix Nucca-docco")def mix(): with click.progressbar(range(5), label='Mixing Nucca-docco') as bar: for i in bar: sleep(1)
まとめ
• click 便利、オススメ
• 特にウェブサービスをコマンドラインで実行したい場合 flask にデコレータがついているので flask mycommand とかできて便利– flask-migrate のコード読んでて知りました
• 実際に使う場合には setup.py でコマンドにする(やり方は click のサイトに書いてある)