Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

werkzeug その1

werkzeugのチュートリアルを見てもいいんだけどせっかくなのでスクラッチから Webアプリケーションを組んでみたいと思う。
最終的にDBを絡めて簡単な投稿フォームとかまでできたらやりたい。

はじめの一歩

とりあえずwerkzeugをインストールする
大概はこれで入る

sudo easy_install werkzeug

その他、必要なものは随時入れていく事にする。

プロジェクトの雛形

インストール後、早速何をどうしたらいいのかわからないのでまずはプロジェクトの雛形を考える。

.

-- example
-- __init__.py
`-- application.py

`-- manage.py

まず最低限の構成から組みあげる。
後々、テンプレートやモデルの置き場を考える。

  • manage.py -- テストサーバ起動、DB作成などの支援スクリプト
  • example/application アプリケーション本体の起動ポイント

初めの一歩

とりあえずテスト用のサーバを起動して何か出力するところまでをやってみよう。

manage.py
from werkzeug import script

def make_app():
    from example.application import Example
    return Example()

def make_shell():
    application = make_app()
    return locals()

action_runserver = script.make_runserver(make_app, use_reloader=True)
action_shell = script.make_shell(make_shell)

script.run()

manage.pyは支援スクリプトになる。
werkzeugでは支援スクリプトも自作することになるわけだが、最初から

  • テストサーバ起動
  • シェルの起動

は簡単にできるような関数を提供している。

make_runserver関数は渡したアプリケーションを起動するサーバを起動する関数を返す。
make_shell関数はインタラクティブシェルで最初から読み込んで置く名前空間の辞書を渡し、シェルを起動する関数を返す。

ここで注目すべきなのはaction_xxxという関数だ。
この関数はscriptのモジュールであるscriptに渡されてないように見える。これには仕掛けがある。
scriptモジュールは呼び出し元のモジュールのaction_で始まる関数をコマンドの引数として解釈する。
なので上記では

manage.py runserver
manage.py shell

が使える。もちろん、独自でドンドン付け足す事も可能である。
この辺はまた改めて紹介する。

application.py
from werkzeug import Response, ClosingIterator

class Example(object):

    def __call__(self, environ, start_response):
        res = Response("Hello")
        return ClosingIterator(res(environ, start_response))

メイン部になるapplicationを定義する。
今回は適当にExampleという名前にしてある。
Exampleの__call__に注目してほしい。実際にはこのメソッドがWSGIインターフェイスになる。
本来は、ここでenvironからRequestを作ったり、ルーティングとか、エラー処理とかする事になる。
WSGIインターフェイスのまま持ちまわるのはしんどいので実際の作るアプリケーションによって使いやすいインターフェイス
各自で定義できる。
WSGIのいい所といえばいいところ。java厨ならばここでServletAPIのようなインターフェイスを構築したりもできるわけ)

werkzeugでは返り値をClosingIteratorで返す。
WSGIの仕様では文字列、文字列を返すイテレータを返すのだが、その際ちょっとだけいろいろ処理をしないといけないので
とりあえずResponseをClosingIterator経由で返す。

起動

とりあえず何が来ても"Hello"と返すアプリケーションを作ったので起動してみる。

python manage.py runserver

で起動。
http://localhost:5000/でアクセスするとHelloと表示されるはず。

今回はここまで。