読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

PythonCLIフレームワークcliffを触ってみる

Python

今回のエンジニアブログを担当する藤岡です。
よろしくお願いします。

今回はcliffというライブラリを使用して、簡単なCLIツールを作ってみたいと思います。
CLIツールはバッチ処理、簡単な自作ツールを作成する際に役に立つかと思います。

cliffは3rd party製のPythonCLIアプリケーションフレームワークです。
複数のコマンドの追加、コマンドライン引数の解析、ログの出力等の機能を補ってくれます。

こちらにパッケージの情報が記述してあります。
pipを使用することで簡単にインストールすることが出来ます。

pip install cliff

今回は簡単な出力を出しながら、cliffの機能について触れていきたいと思います。


今回作成するツールのディレクトリ構成は以下のようになっております。

sample_app  
|  
|-- sample_app  
|       |-- __init__.py  
|       |-- hello.py  
|       |-- main.py  
|-- setup.py  

1, 必須となる機能の実装

■ 大本となるアプリケーションの実装
cliffでは、アプリケーションクラスを軸として様々なコマンドを実行していきます。

main.py

# -*- coding: utf-8 -*-  
  
from cliff.app import App  
from cliff.commandmanager import CommandManager  
  
import sys  
import logging  
  
class SampleApp(App):  
      
    def __init__(self):  
        super(SampleApp, self).__init__(  
                description=u'sample application',  
                version=u'0.1',  
                command_manager=CommandManager(u'sample_app.command'),                   
        )  
  
def main(argv=sys.argv[1:]):  
    sample_app = SampleApp()  
    return sample_app.run(argv)  

cliff.app.Appを継承したクラスはツールの軸となる、アプリケーションに紐付けられます。
このAppクラスに様々なコマンドを登録し、呼び出すことが可能になります。

cliff.app.Appを継承したクラスは、run関数を呼ぶことで実行されます。
上記のコードだと、main関数が呼び出されることで、アプリケーションが動き出します。

CommandManagerのコンストラクタ引数では、setup.pyに記述されているentry_pointグループ名を渡します。
そうすることで、entry_point内のコマンド達を取得することが出来ます。

■ コマンドの実装
それでは、上記で作成したSampleAppに簡単な出力を行うhelloコマンドを登録してみます。

hello.py

# -*- coding: utf-8 -*-  
    
from cliff.command import Command  
    
class Hello(Command):  
    "A Hello command that prints a message."  
    
    def take_action(self, parsed_args):  
        print u'Hello!! sample application!!'  

cliff.command.Commandを継承したクラスはアプリケーションのコマンドとして実装可能になります。
コマンドクラスは、コマンド実行時にtake_action関数が呼び出されます。
上記のコードだと、"Hello!! sample application!!"と出力されるはずです。

■ setup.pyの実装
cliffのコマンドの実装はsetup.pyのentry_pointに記述をすることで実装することが可能です。

setup.pyの詳細は割愛させていただきます。
詳細はこちら。

・cliffパッケージが必須となるのでinstall_requires要素内にcliffの記述を忘れない
エントリーポイント要素内に登録したいコマンドのエントリーポイントグループを記述する(下記の例ですとsample_app.commandの部分です)

cliffアプリケーションのsetup.pyでは、この2つの実装が大切になってきます。

setup.py(一部分)

install_requires=[  
    u'cliff',  
],  
entry_points={  
    u'console_scripts' : [  
        u'sampleapp = sample_app.main:main',  
    ],  
    u'sample_app.command' : [  
        u'hello=sample_app.hello:Hello',  
    ],  
},  

各コマンドの登録フォーマットですが、
{アプリケーション名}={モジュール名}:{関数}
{コマンド名}={モジュール名}:{クラス名}
てな感じになってます。

上記の例ですと、sampleappコマンドはsample_appモジュール内のmainモジュールのmain関数を呼びだし、helloコマンドはsample_appモジュール内のhelloモジュールのHelloクラスを呼び出しています。

必要な実装が終わったら、アプリケーションをインストールします。
下記のコマンドで、作成したCLIアプリケーションをインストール出来ます。

python setup.py install

実行結果はこちら。
スクリーンショット 2015-03-26 12.41.05
アプリケーション内のhelloコマンドが実行され、Helloクラスのtake_action関数が呼ばれていることが確認出来ました。

また、cliffではデフォルトで様々なオプションが追加されており、ヘルプ等のオプションをサポートしてくれます。
スクリーンショット 2015-03-26 11.48.28

2, コマンドライン引数の実装

cliffでは、コマンド毎にコマンドライン引数を設定することが可能です。
引数を受け取って、argument valueを出力してみます。

hello.py

# -*- coding: utf-8 -*-  
  
from cliff.command import Command  
  
class Hello(Command):  
    "A Hello command that prints a message."  
  
    def get_parser(self, prog_name):  
        parser = super(Hello, self).get_parser(prog_name)  
  
        parser.add_argument(u'--arg1', default=None, metavar=u'<引数1>', help=u'引数1')  
        parser.add_argument(u'--arg2', default=None, metavar=u'<引数2>', help=u'引数2')  
        parser.add_argument(u'--arg3', default=None, metavar=u'<引数3>', help=u'引数3')  
  
        return parser  
  
    def take_action(self, parsed_args):  
  
        print parsed_args.arg1  
        print parsed_args.arg2  
        print parsed_args.arg3  
  
        print u'Hello!! sample application!!'  

cliffのCommandクラスを継承したクラスでget_parser関数をオーバーライドし、その中でadd_argument関数によりコマンドライン引数を追加しています。


実行結果はこちら。
スクリーンショット 2015-03-26 12.01.09
コマンドライン引数の受け取りが出来ています。

また、add_argument関数内のmetavar, helpを指定することで、コマンドの説明を明示する事ができます。
スクリーンショット 2015-03-26 12.01.32

3, インタラクティブシェル

引数なしでアプリケーションを実行するとインタラクティブシェルが動き出します。
インタラクティブモードでは、各コマンドを打ち込むだけで実行結果を出力することが出来ます。

スクリーンショット 2015-03-26 12.56.05

以上になります。
CLIアプリケーションを簡潔に作ることが出来るので、是非お試し下さい。