コマンドラインインターフェイス(CLI)は、テキストコマンドを使用してコンピュータと対話する方法です。
GUIを必要としない多くのツールは、CLIツール/ユーティリティとして記述されています。Pythonには argparse
モジュールが組み込まれていますが、同様の機能を持つ他のライブラリも存在します。
これらのライブラリは、CLIスクリプトを書く際に、オプションやフラグの解析のようなサービスから、より高度なCLI機能までを提供することができます。
この記事では、最小限のコードでCLIを作成するのに便利なGoogle Inc.のPython Fireライブラリについて説明します。
インストール
早速、pip
を使ってライブラリをインストールしてみましょう。
prompt command parameter1 parameter2 ... parameterN
Python Fireは、関数やクラス、辞書、リストなど、あらゆる Python オブジェクトに対して動作します。ここでは、いくつかの例を通して
Python Fire` ライブラリの使い方を理解しましょう。
Python FireでCLIアプリケーションを生成する
Fire_cli.py` というスクリプトを作成し、その中に関数を記述します。
$ ls
README.md
python
このプログラムをPythonのシェルで実行すると、次のような出力が得られます。
$ ls -l
-rwxrwxrwx 1 pandeytapan pandeytapan 10 Sep 23 18:29 README.md
drwxrwxrwx 1 pandeytapan pandeytapan 512 Sep 23 18:29 python
このスクリプトをPython Fireを使って簡単にCLIアプリケーションにすることができます。
$ ls -l --time-style=full-iso
-rwxrwxrwx 1 pandeytapan pandeytapan 10 2020-09-23 18:29:25.501149000 +0530 README.md
drwxrwxrwx 1 pandeytapan pandeytapan 512 2020-09-23 18:29:25.506148600 +0530 python
Fire.Fire()の呼び出しは、モジュール
fire_cli.pyをFire CLIアプリケーションに変えます。さらに、
greet_mankind()`関数をコマンドとして自動的に公開しています。
上記のスクリプトをCLIとして保存して実行するには、以下のようにします。
$ pip install fire
復習のために、呼び出しを分解してみましょう。
- $ はプロンプトです。
- python はコマンドインタプリタです。
- fire_cli.py は、CLIコマンドを含むモジュールです。
- greet_mankind はコマンドです。
コマンドに引数を渡す
名前をパラメータとして受け取り、独自のグリーティングメッセージを表示するCLIアプリケーションをもう一つ作ってみましょう。
def greet_mankind():
"""Greets you with Hello World"""
return 'Hello World'
ここでは、文字列 name
を受け取る関数が用意されています。Python Fireはこれを自動的に拾って、 greetings
の呼び出しの後に引数を与えると、その入力を name
パラメータにバインドします。また、 --help
コマンドのドキュメントのようなコメントも追加しています。
以下は、このコマンドをコマンドラインから実行する方法です。
>>> from fire_cli import greet_mankind
>>> greet_mankind()
'Hello World'
>>>
Fire CLI アプリケーションは、 --help
フラグを使用して、Python のドキュメントから生成されたコマンドの説明を確認することができます。
import fire
def greet_mankind():
"""
Returns a textual message
"""
return 'Hello World'
if __name__ == '__main__':
fire.Fire()
関数をエントリーポイントに設定する
わずかな修正で greetings()
関数のコマンドラインへの公開を制御し、それをデフォルトのエントリーポイントとして設定することができます。
$ python fire_greet_mk_cli.py greet_mankind
Hello World
このようにコマンドを実行します。
import fire
def greetings(name):
'''
Returns a greeting message
Parameters
----------
name : string
String that represents the addresses name
Returns
-------
string
greeting message concatenated with name
'''
return 'Hello %s' % name
if __name__ == '__main__':
fire.Fire()
Fire()を使って暗黙のうちに
greetings` をエントリポイントとして定義しているので、今回はもうコマンドを呼び出す必要はありません。ここで一つ注意しなければならないのは、このバージョンでは引数を一つしか渡せないということです。
$ python fire_greet_cli.py greetings Robin
Hello Robin
引数のパース
Fire ライブラリはクラスも扱うことができる。ここでは、 start
と end
の間の数値のリストを生成して返すクラス CustomSequence
を定義してみよう。
python fire_greet_cli.py greetings --help
NAME
fire_greet_cli.py greetings - Returns a greeting message
SYNOPSIS
fire_greet_cli.py greetings NAME
DESCRIPTION
Returns a greetings message
POSITIONAL ARGUMENTS
NAME
String that represents the addresses name
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
このコマンドラインユーティリティを使用して、シーケンスを生成する方法について説明する。
import fire
def greetings(name):
'''
Returns a greeting message
:param name: string argument
:return: greeting message appended with name
'''
return 'Hello %s' % name
if __name__ == '__main__':
fire.Fire(greetings)
関数の代わりにクラスを使用したのは、関数と違ってコンストラクタに引数を渡したい場合、常にハイフン2つでコマンドラインフラグとして表現しなければならないからです (例: --offset=2
)。
そのため、私たちの CLI アプリケーションでは、クラスのコンストラクタに渡すオプションの引数 --offset
をサポートしています。これは、2つの連続した生成値の差を制御することで、出力を変更します。
以下は、オフセット値を 2 とした場合の出力です。
$ python fire_greet_cli.py Robin
Hello Robin
コンストラクタの引数は常にフラグシンタックスを使用して渡されますが、他のメソッドや関数の引数は位置指定や名前指定で渡されています。
$ python fire_greet_cli.py Robin Hood
ERROR: Could not consume arg: Hood
...
$ python fire_greet_cli.py Robin
Hello Robin
generateコマンドの使用方法は、
–help` フラグを使用して確認することができます。これは、CLI の使用情報を提供します。
import fire
class CustomSequence:
'''Class that generates a sequence of numbers'''
def __init__(self, offset=1):
'''
Parameters
----------
offset : int, optional
Number controlling the difference between two generated values
'''
self.offset = offset
def generate(self, start, stop):
'''
Generates the sequence of numbers
Parameters
----------
start : int
Number that represents the elements lower bound
stop : int
Number that represents the elements upper bound
Returns
-------
string
a string that represents the generated sequence
'''
return ' '.join(str(item) for item in range(start, stop, self.offset))
if __name__ == '__main__':
fire.Fire(CustomSequence)
モジュールで --help
を使用すると、その使用情報を得ることができます。
$ python fire_gen_cli.py generate 1 10
1 2 3 4 5 6 7 8 9
Fire Flags
Fire CLI には多くのフラグが組み込まれています。すでに --help
を見てきましたが、もうひとつの便利なフラグが --interactive
です。このフラグを使うと、Python REPL モードになり、モジュールがすでに定義されている状態になります。
これはコマンドをテストするのに非常に便利です。
$ python fire_gen_cli.py generate 1 10 --offset=2
1 3 5 7 9
もし、あるコマンドで --help
と --interactive
フラグの両方を使用したい場合は、以下のようになります。
$ python fire_gen_cli.py generate --start=10 --stop=20
10 11 12 13 14 15 16 17 18 19
$ python fire_gen_cli.py generate 10 20
10 11 12 13 14 15 16 17 18 19
$ python fire_gen_cli.py generate --start=10 --stop=20 --offset=2
10 12 14 16 18
結論
GoogleのPython Fireライブラリは、ほぼすべてのPythonオブジェクトのコマンドラインインターフェース(CLI)を迅速かつ容易に生成する方法です。
この記事では、Python Fireのインストール方法と、簡単なコマンドラインインターフェイスを生成する方法を説明しました。
</flags