はじめに
Pythonモジュールにclickというモジュールがある。
こちらで分かりやすく解説されているので主要な使い方は公式ドキュメントや前述を参照すれば良いがちょっとした事をしたいときのTipsが無いので追記のようなイメージでメモを残すことにする。
callbackを利用する際の注意点
clickには受け取った値に対し、callback処理することができる。
ただし、callback validationをかけた後にその値を使う場合、
callbackで微妙にハマりどころがあるので記録しておく
ちなみに公式ドキュメントはこちら
例えばこんなコードを書いて、addrオプションが ipaddress 表記になっているかチェックする場合
した上で値を返すようなコードを書く場合はちゃんと returnで返してやらないと def cmd の方に
addr argumentが来ないので注意が必要。
import click
import ipaddress
def validate_ipaddress(ctx, param, value):
try:
addr = ipaddress.ip_address(value)
except ValueError:
msg = f"addr must be ip address format as 'x.x.x.x'"
raise click.BadParameter(msg)
return str(addr)
@click.command()
@click.option('--addr', required=False,
type=str, callback=validate_ipaddress,
help='address')
def cmd(addr):
set_loglevel(debug)
clickのオプションを使い回す
いくつかプログラムを作る必要があり、共通のオプションを使いたい場合は
適当に関数などを定義して呼び出したいと思う。そんなときはこんな風にする。
- command_opt.py
import functools
import click
def mode_options(func):
@click.option('-t', '--interval', required=True, type=int, default=5,
help="run program every N minutes. (default: 5min)")
@click.option('--silent/--no-silent',
help='Silent mode - print result or not.(default: False)')
@click.option('--multithread/--no-multithread', help='Multithread mode (default: False)')
@click.option('--debug/--no-debug', help='Debug mode (default: False)')
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
- click_program.py
import click
import time
import schedule
from command_optimport inventories_options, mode_options
@click.command()
@inventories_options
@mode_options
def cli(hostname, ip, os, interval, silent, multithread, debug):
try:
app = Runner(hostname, ip, os, silent, multithread, debug)
if interval == 0:
app.run()
else:
schedule.every(interval).minutes.do(app.run)
while True:
schedule.run_pending()
time.sleep(1)
except Exception as e:
msg: str = "Cannot run program: %s" % str(e)
print(msg)
sys.exit(1)
def main():
cli()
sys.exit(0)
if __name__ == "__main__":
main()
bash補完ができるようになるおまじない
基本的にはこちら
ただし、.pyのままだと実行できないのでpyinstallerを使ってバイナリ化するか
setuptoolを書くなどして、”インストール”してしまうこと。