2009年12月11日

repoze.bfgで遊びながら(略 (2)

前回repoze.bfgをbuildoutで使う環境を作ったので、なんか実装してみましょう。
repozeは、一般的にmodel-view-templateの構成をするようですが、viewだけの実装も可能です。

viewを実装する
src/board/views.py がすでにviewを実装するモジュールとして存在しているので、ここに追加してみます。

import webob
def hello(request):
return webob.Response(body='Hello, world', content_type="text/plain")

既に、my_viewという関数が実装されていますが、こちらはtemplate使ってるので、dictを返しています。
今回は、templateなしで実装するので、自分でResponseまで作成します。
Responseのコンストラクタで、bodyに渡した内容が、httpレスポンスのボディとなります。
content typeの指定も可能です。

テストする
あまりテストする必要もないですが、一応やってみましょう。

import webob
def hello(request):
"""
>>> req = webob.Request({})
>>> res = hello(req)
>>> res.body
'Hello, world'
>>> res.content_type
'text/plain'
"""
return webob.Response(body='Hello, world', content_type="text/plain")

doctestで書いています。
前回作っておいた、webtestを実行します。

bin/webtest

※テストが2つ実行されますが、1つは自動生成されたテストです。

viewを登録する
作成したviewをWebアプリケーションから呼び出されるように登録します。
viewの登録方法は2種類あります。

  • zcmlファイルに記述する
  • Configuratorのadd_viewメソッドを呼ぶ

今回はConfiguratorを使うことにしましょう。
src/board/run.py の中でConfiguratorを作成しているので、make_wsgi_appが呼ばれる前に、add_viewメソッドを追加します。

import views
config.add_view(views.hello, name='hello')

この場合は、helloという名前でURLにマッピングされます。

Webアプリケーションのテストを追加します。
tests.pyがすでにありますが、中身を消して、改めてテストを書きます。

import webtest
from paste.deploy.loadwsgi import loadapp
import os
config = os.path.join(os.path.dirname(__file__), '..')

def test_hello():
app = webtest.TestApp(loadapp('config:board.ini', relative_to=config))
res = app.get('/hello')
assert res.status_int == 200
assert res.body == 'Hello, world!'


repoze.bfgはPasteDeployを利用しているので、WSGIアプリケーションもPasteDeploy経由で取得します。paste.deploy.loadwsgi:loadappで取得できますが、board.iniは一段上のディレクトリにあるので、os.pathなどを使って特定しています。
wsgiアプリケーションを取得したら、webtest:TestAppでラップします。
TestAppは、getやpostなどの呼び出しが簡単にできるようになっています。
Responseが帰ってくるので、レスポンスステータスやボディを確認します。
このテストも、webtestから実行されます。

bin/webtest


アプリケーションを実行する
アプリケーションは、bin/pasterで実行できます。
※前回のbuildout.cfgでは、実行に失敗します。以下のように直しましょう。

[repoze]
recipe = zc.recipe.egg
eggs =
PasteScript
repoze.bfg
board




bin/paster src/board.ini

これで、http://localhost:6543/hello にアクセスすると、"Hello, world!"と表示されます。