10:Webリクエストとレスポンスの処理(10: Handling Web Requests and Responses)¶
Webアプリケーションは受信したリクエストを処理してレスポンスを返します。Pyramidはリクエストとレスポンスを便利で信頼できるものにします
目的(Objectives)¶
- Pyramidnのリクエストリクエストとレスポンスの選択についての背景を学びます。
- リクエストからデータを取得します。
- レスポンスヘッダーの情報を変更します。
背景(Background)¶
Web開発とはWebのリクエストを処理することをです。これはWebアプリケーションの重要な部分であるため、Web開発者はWebリクエストとWebレスポンスを返すための堅牢で成熟したソフトウェアセットが必要です。
PyramidはPythonのWeb開発の世界(仮想環境、パッケージジング、Cookiecutter、Python3系を最初に採用するなど)に上手に適合しています。Pyramidはリクエストとレスポンスの処理のために評価がよいPythonライブラリの WebOb に目を向けました。前回の例の request
の hello_world
についてはPyramidの based on WebOb に基づきます。
手順(Steps)¶
最初に、
view_classes
での結果をコピーします:$ cd ..; cp -r view_classes request_response; cd request_response $ $VENV/bin/pip install -e .
request_response/tutorial/__init__.py
でルートを簡略化します:1 2 3 4 5 6 7 8 9
from pyramid.config import Configurator def main(global_config, **settings): config = Configurator(settings=settings) config.add_route('home', '/') config.add_route('plain', '/plain') config.scan('.views') return config.make_wsgi_app()
request_response/tutorial/views.py
のビューが必要です:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
from pyramid.httpexceptions import HTTPFound from pyramid.response import Response from pyramid.view import view_config class TutorialViews: def __init__(self, request): self.request = request @view_config(route_name='home') def home(self): return HTTPFound(location='/plain') @view_config(route_name='plain') def plain(self): name = self.request.params.get('name', 'No Name Provided') body = 'URL %s with name: %s' % (self.request.url, name) return Response( content_type='text/plain', body=body )
request_response/tutorial/tests.py` のテストを更新します:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
import unittest from pyramid import testing class TutorialViewTests(unittest.TestCase): def setUp(self): self.config = testing.setUp() def tearDown(self): testing.tearDown() def test_home(self): from .views import TutorialViews request = testing.DummyRequest() inst = TutorialViews(request) response = inst.home() self.assertEqual(response.status, '302 Found') def test_plain_without_name(self): from .views import TutorialViews request = testing.DummyRequest() inst = TutorialViews(request) response = inst.plain() self.assertIn(b'No Name Provided', response.body) def test_plain_with_name(self): from .views import TutorialViews request = testing.DummyRequest() request.GET['name'] = 'Jane Doe' inst = TutorialViews(request) response = inst.plain() self.assertIn(b'Jane Doe', response.body) class TutorialFunctionalTests(unittest.TestCase): def setUp(self): from tutorial import main app = main({}) from webtest import TestApp self.testapp = TestApp(app) def test_plain_without_name(self): res = self.testapp.get('/plain', status=200) self.assertIn(b'No Name Provided', res.body) def test_plain_with_name(self): res = self.testapp.get('/plain?name=Jane%20Doe', status=200) self.assertIn(b'Jane Doe', res.body)
テストを実行します:
$ $VENV/bin/py.test tutorial/tests.py -q ..... 5 passed in 0.30 seconds
Pyramidアプリケーションを以下のように実行します:
$ $VENV/bin/pserve development.ini --reload
ブラウザで http://localhost:6543/ を開きます。 http://localhost:6543/plain にリダイレクトされます。
ブラウザで http://localhost:6543/plain?name=alice を開きます。
分析(Analysis)¶
今回のビュークラスでは2つのルートと2つのビューがあり、最初の方はHTTPリダイレクトで2番目のビューにつながります。Pyramidはビューから特別なオブジェクトを返すか、特別な例外を発生させることによって、 generate redirects を生成できます。
今回のPyramidのビューは、request.url
からアクセスしたURLを取得します。また、http://localhost:6543/plain?name=alice にアクセスした場合は、nameはレスポンスボディに含まれます:
URL http://localhost:6543/plain?name=alice with name: alice
最後にレスポンスのコンテンツタイプとボディを設定してレスポンスを返します。
ユニットと機能テストを更新して、コードがリダイレクトを行うことを証明しましたが、 /plain?name は送信した/されなかったのでしょうか?
エクストラクレジット(Extra credit)¶
- ルーティングを返すのではなく
raise HTTPFound(location='/plain')
でもできますか?もしそうなら、違いは何ですか?