Flask に manage.py が欲しい

そういえば、どこかでタイトルのような話をどこかで見た気がするけど忘れた。

Djangoでは、runserverや、カスタムでコマンドを定義したいときに、manage.pyを使うらしいが、それと似たような事ができる、エクステションもある。Flask-Scriptというヤツだ。

http://packages.python.org/Flask-Script/

以下覚え書き

インスール

pip install Flask-Script

簡単な例

  • manage.pyとかいうファイル名でこんな感じのを作る
  • from flasksample import app は 自分で作ったりアプリで、app はFlask()のインスタンスとする
from flaskext.script import Server, Manager
from flasksample import app

manager = Manager(app)

if __name__ == "__main__":
    manager.run()

この状態で、下記のように実行すると既にデフォルトで「shell」と「runserver」が使えるようになってる。

$ python manage.py 
  shell      Runs a Python shell inside Flask application context.
  runserver  Runs the Flask development server i.e. app.run()

runserverを実行したい場合はこう実行する。

$ python manage.py runserver
 * Running on http://127.0.0.1:5000/
 * Restarting with reloader

カスタムコマンドを作る

大きく分けてやり方は二つある。

  • それ用の関数デコレータを利用する
  • Commandクラスを継承して新しいコマンドを作る

それ用の関数デコレータを利用する。

manager = Manager(app)

@manager.command
def haruo():
    """ print Haruo is World """
    print 'Haruo is World'

こうすると、haruoコマンドが追加される。関数のdocstringがコマンド一覧を表示したときの説明に使われる。

$ python manage.py 
  haruo      print Haruo is World
  shell      Runs a Python shell inside Flask application context.
  runserver  Runs the Flask development server i.e. app.run()
$ python manage.py haruo
Haruo is World

関数に対して引数をわたすにはこう。

@manager.command
def haruo(name):
    """ print Haruo is World """
    print 'Haruo is '  + name
$ python manage.py haruo Gold
Haruo is Gold

オプション付きのコマンドにするときはoptionデコレータを使う

@manager.option('-s', '--semeru', help='SEMERU HITO')
@manager.option('-u', '--ukeru', help='UKERU HITO')
def boyslove(semeru, ukeru):
    """ boyslove """
    print semeru + ' x ' + ukeru
$ python manage.py boyslove -s oyakata -u podhmo
oyakata x podhmo

このとき「-h」でヘルプ内容が確認できる。

$ python manage.py boyslove -h
usage: manage.py boyslove [-h] [-u UKERU] [-s SEMERU]

boyslove

optional arguments:
  -h, --help            show this help message and exit
  -u UKERU, --ukeru UKERU
                        UKERU HITO
  -s SEMERU, --semeru SEMERU
                        SEMERU HITO

Commandクラスを継承して新しいコマンドを作る

Commandクラスを継承して作ることもできる。上のboysloveコマンドをこの方式で作り直すとこんな感じ。

from flaskext.script import Manager, Command, Option
from flasksample import app

manager = Manager(app)

class BoysLove(Command):
    """ boyslove command """
   
    option_list = (
        Option('-s', '--semeru', dest='semeru', required=True, help='semeru hito'),
        Option('-u', '--ukeru',  dest='ukeru', required=True, help='ukeru hito'),
    )
    def run(self, semeru, ukeru):
        print semeru + ' x ' + ukeru

manager.add_command("boyslove", BoysLove())

if __name__ == "__main__":
    manager.run()


ややこしいバッチ処理を作るときは、Commandクラスを継承した方がよいかも。

以上おわり。