Google Open Source プロジェクトの1つ、
Python用コマンドライン・インターフェース作成ライブラリ「Python Fire」の紹介です。

MacやLinuxを含むUnix系の環境で、運用 / 開発している人は、タスクを自動化する為に
作成したスクリプトを'.bashrc'内に 'alias'としてコマンド登録。
crontab等のスケジュールコマンドの1として使用している人も多いのではないのでしょうか。

特にサーバー環境 & Pythonでバッチ処理等のコードを 書いている人に役立ちそうなライブラリが
Python Fire」です。
 

Python Fireで出来ること

・CLI上で実行する' 実行ファイル コマンド名  [パラメーター] ' 形式のプログラムが簡単に書ける
( * 例 :  python test.py 関数名 引数 )
 

Python Fireのインストール

python-fireはpipパッケージで提供されているので、
コマンドライン上から"pip"コマンドを使ってインストールします。

# pipコマンドでインストール
pip install fire # OR pip3 install fire
# ソースコードをを'git clone'で入手し、pythonスクリプトからインストールする場合
python setup.py install # OR python3 setup.py install

 

Python Fireの最低限の使い方

下のスニペットはpython-fireを使った文字列を返すだけ最低限のサンプルです。

# hello.py
import fire

class Hello(object):
    """python-fireを使った文字列を返すだけのサンプル"""

    def greeting(self, string):
        # returnの値がアウトプットされます
        return "hello " + str(string)
        pass

pass

if __name__ == '__main__':
    fire.Fire(Hello)  # Helloクラスをfireに登録

 ' fire ' パッケージを読み込んでいること、' fire.Fire() ' 内にクラスを登録。
よくあるサンプルコードと変わりありませんが、実行可能な'greeting'コマンドが作成されました。

このサンプルの場合はクラス内の関数名がコマンド名として自動的に登録されています。
( * 新たに関数を追加すれば コマンドも追加され、関数の引数がパラメーターになります )

# コマンドライン上からhello.py、greetingコマンドを実行
$ python hello.py greeting world
# $ python hello.py greeting --string=world #こちらでも可能

# output: hello world

 

複数のクラスを使う場合

続いては、複数のクラスを使う時のサンプルです。

コマンド(関数)が増えてコードが長くなった場合でも、クラスやファイルを分割する事が可能で、
fireが実行するクラスの '__init__ ( コンストラクタ )' 内で定義した変数名がコマンド名になります。 
( *  '__init__' 内にself変数を書くとコマンドとして認識されるので、1クラスで処理を書く場合はコンストラクタを使わないほうがよさそうです )

下のスニペットは コマンドを叩くと日本とアメリカの時刻が表示されます。
( * 下記の場合はコメンド名 ' jp ' でJapanクラス、' usa 'でAmericaクラスを割り当てています )

# TimerWrapper.py
import fire
from datetime import datetime
import pytz

class America(object):
    """ アメリカの時刻を表示 """

    def NY(self):
        time = str(datetime.now(pytz.timezone('America/New_York')))
        return time[0:19]
        pass

    def LA(self):
        time = str(datetime.now(pytz.timezone('America/Los_Angeles')))
        return time[0:19]
        pass
pass

class Japan(object):
    """ 日本の時刻を表示 """

    def now(self):
        time = str(datetime.now(pytz.timezone('Asia/Tokyo')))
        return time[0:19]
        pass
pass

class TimeWrapper(object):
    """ 時刻を表示するクラス """
    def __init__(self):
        # Americaクラス内の 'NY', 'LA'関数がコマンドとして登録
        self.usa = America()  # Americaクラスをusaコマンドとして登録

        # Japanクラス内の 'now' 関数がコマンドと登録される
        self.jp = Japan()    # Japanクラスをjpコマンドとして登録
        pass
pass

if __name__ == '__main__':
    fire.Fire(TimeWrapper)
$ python TimeWrapper.py usa NY
# output: 2017-03-30 02:35:30 *ニューヨークの時刻を表示
$ python TimeWrapper.py usa LA
# output: 2017-03-29 23:35:34 *ロサンゼルスの時刻を表示
$ python TimeWrapper.py jp now 
# output: 2017-03-30 15:37:27 *日本の時刻を表示

# ファイルを直接実行すると用意されているコマンドや説明が表示されます
$ python3 TimeWrapper.py
Type:        TimeWrapper
String form: <__main__.TimeWrapper object at 0x10c4ddb70>
File:        ~/Documents/program/python/fire/TimeWrapper.py
Docstring:   時刻を表示するクラス

Usage:       TimeWrapper.py
             TimeWrapper.py jp
             TimeWrapper.py usa

1つのpythonファイルを通してコマンドが作成出来るので、コマンドが多数ある場合でも
'.bashrc OR .zshrc' 内に実行する パスやコマンド名の登録は1つにまとめられそうです。

Summary

以上がPython Fireの紹介でした。

実際にPython Fireで 自身で使っていたバッチ処理をFire用に書き直し( 移植 )てみて、
以下の様な印象を受けました。

* Python Fireを触って感じたこと
- ライブラリ特有の書き方の作法がホボ無いに等しいので、学習コストが少ない
- 上手に設計すれば1ファイルを通してコマンドが綺麗にまとめられる (aliasに登録したコマンドは減らせる)
- コマンドリスト、ヘルプを表示する機能を作らなくていいので、CLIアプリ早く作れる

- 既存のPythonで書いた処理を移植するのも難しくはなかった
- crontabで定期的に実行する処理を書く時には便利かも
- コマンドをまとめる実行クラスには処理を書かないほうがいい ( コマンド定義のみが良さそう )

Python使いの人にはオススメ出来るライブラリなので、気になった人はゼヒ×2チェックしてください!

GitHub : google/python-fire

 

この記事のカテゴリ

プログラミング

この記事のタグ

サーバー関連 , Python , 効率化

Socialシェアボタン

スポンサーリンク