2016-04-26

PythonのWebアプリフレームワークFalcon試してみた

Falconという高速・シンプルなWebアプリフレームワークを触ってみましたー

PHPの高速WebアプリフレームワークでPhalconというのがありますが、PythonはFalconになります。

ということで、試しにFalconでHerokuにアプリ立ててみました↓

握手会適正判定フォーム

Falconの概要

インストール

安定のpip。WSGIサーバのgunicornも一緒にインストールしておく。
$ pip install falcon gunicorn

基本的な使い方

GET/POSTの例(index.pyとして作成)
#!/usr/bin/env python
# -*- coding:utf-8 *-

import falcon


class HogeResource(object):
    def on_get(self, req, res):
        print(req.headers)
        print(req.params)
        print(req.cookies)
        res.status = falcon.HTTP_200
        res.body = 'Hello World'
        res.content_type = 'text/plain'

    def on_post(self, req, res):
        print(req.headers)
        print(req.method)
        print(req.protocol)
        print(req.content_type)
        print(req.stream.read())

        res.status = falcon.HTTP_200
        res.content_type = 'text/plain'
        res.body = 'post!!'

app = falcon.API()
app.add_route('/hoge_resoure', HogeResource())

あとはWSGIアプリとして動かせばOK

$ gunicorn index:app --reload

Cookie操作

print req.cookies['{cookie_key}'] # req.cookiesはディクショナリ
res.set_cookie("{cookie_key}", "{cookie_value}", secure=True) # secure未指定だとデフォルトTrue

リダイレクト

最新だとException投げればリダイレクトできるみたいですが、0.3系は以下のようにして対応
res.status = falcon.HTTP_301
res.set_header('Location', 'http://www.google.com')

Hook

デコレータを利用して、任意のハンドラの前処理、後処理をする仕組み。こんな感じで書く

def before(req, res, resource, params):
    print('***before start***')
    print(req)
    print(res)
    print(resource)
    print(params)
    print('***before end***')

def after(req, res, resource):
    print('***after start***')
    print(req)
    print(res)
    print(resource)
    print('***after end***')

...
    @falcon.before(before)
    @falcon.after(after)
    def on_get(self, req, res):
        pass
...

ミドルウェア

Hookのグローバルバージョン。任意のハンドラではなく全てのハンドラに適用される。
class ExampleComponent(object):
    def process_request(self, req, resp):
        print('***process request start***')
        print(req)
        print(resp)
        print('***process request end***')

    def process_resource(self, req, resp, resource):
        print('***process resource start***')
        print(req)
        print(resp)
        print(resource)
        print('***process resource end***')

    def process_response(self, req, resp, resource):
        print('***process response start***')
        print(req)
        print(resp)
        print(resource)
        print('***process response end***')

app = falcon.API(middleware=[ExampleComponent()])

Hookと組み合わせて利用すると以下の順番で処理される模様

  1. Middleware process_request
  2. Middleware process_resource
  3. Hook before
  4. Execute Handler
  5. Hook after
  6. Middleware process_response

Herokuにデプロイしてみる

gunicornのProcfileを書いてデプロイすればOK。
$ git init
$ heroku apps:create {application_name}
$ pip install falcon gunicorn
$ pip freeze > requirements.txt
$ echo "web: gunicorn index:app --log-file -" > Procfile
$ git add .
$ git commit -m "initial"
$ git push heroku master

補足

テンプレートエンジンがついていないので、自前で用意してあげる必要がある。jinja2使う場合は
$ pip install jinja2

でインストールして、以下のように記述すればOK

from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('./templates/', encoding='utf8'))

...
res.body = tpl.render({'hoge':'fuga'})
...

ただし、テンプレートエンジンのコストでFalconの高速性をスポイルするかもしれないので、そこらへんは検討する必要があるかも。HTMLを返すアプリではなくJSON、XMLを返すAPIサーバ向けのフレームワーク、というイメージです。

参考URL

このエントリーをはてなブックマークに追加