PythonでFireを使ったコマンドラインインタフェース(CLI)の生成

コマンドラインインターフェイス(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 ライブラリはクラスも扱うことができる。ここでは、 startend の間の数値のリストを生成して返すクラス 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

タイトルとURLをコピーしました