PythonでClickとnetrcを併用する

Created 2018年6月18日16:02
Updated 2018年6月18日16:03
Categories Python

Pythonのコマンドラインパーサーのclickとnetrcを一緒に使う時に少し工夫したのでメモ。

click + netrc

clickでWebサービスなどにログインするコマンドを作る際、例えばこんな感じで書くと思います。

import click


@click.option("--username", "-u", prompt="Please input your username")
@click.option("--password", "-p", prompt="Please input your password", hide_input=True)
def my_command(username, password):
    print(username, password)

このコマンドはユーザー名とパスワードを引数に持ちますが、指定されなかった場合はプロンプトでそれぞれ入力させるような動作をします。

ただし、usernameやpasswordをいちいち指定するのは面倒なので、netrcなどのファイルを使えると便利です。

netrcを使う場合は

import click
import netrc

auth = netrc.netrc()
username, _, password = auth.authenticators("service_name")


@click.option("--username", "-u", default=username)
@click.option("--password", "-p", default=password)
def my_command(username, password):
    print(username, password)

のようにしてやると良いのですが、promptオプションとdefaultオプションは併用できません(確かdefaultオプションが優先されたと思います)。

netrcがある場合だけ使って、そうでない場合はpromptを表示するような動作をさせたい場合、次のように書くと良いかもしれません。

import click
import netrc

try:
    auth = netrc.netrc()
    username, _, password = auth.authenticators("service_name")
    username_options = {"default": username}
    password_options = {"default": password}
except (OSError, FileNotFoundError, TypeError) as e:
    username = password = None
    username_options = {"prompt": "Please input your username/email"}
    password_options = {"prompt": "Please input your password", "hide_input": True}


@click.option("--username", "-u", **username_options)
@click.option("--password", "-p", **password_options)
def my_command(username, password):
    print(username, password)

辞書にオプションを入れて、clickに渡す際に名前付きで展開しています。

netrcから認証情報が取得できればdefaultオプション、そうでなければpromptやhide_inputオプションを渡すようにしています。

なお、exceptでキャッチしているエラーについては、

  • OSError: Windowsでnetrcを使うと発生
  • FileNotFoundError: netrcが無い時に発生
  • TypeError: netrcに認証情報が記述されていないときに発生

となります。もしかしたら要らないのがあるかもしれません・・・

ともかく、辞書でうまいこと引数展開できるのはPythonらしい便利さがありますね。

コメントを投稿

コメント