29
WAFをつくってる話 大阪Pythonユーザの集まり 2016/04 MASASHI SHIBATA ! c_bata_

Webフレームワークを作ってる話 #osakapy

Embed Size (px)

Citation preview

Page 1: Webフレームワークを作ってる話 #osakapy

WAFをつくってる話

大阪Pythonユーザの集まり 2016/04

MASASHI SHIBATA! c_bata_

Page 2: Webフレームワークを作ってる話 #osakapy

@c_bata_

django / flask / pandas明石高専

Page 3: Webフレームワークを作ってる話 #osakapy

話すこと

1. WSGIの話とか

2. WAFに欲しい機能を考える

3. Kobinの紹介

4. Kobinにおける取り組み

Page 4: Webフレームワークを作ってる話 #osakapy

WSGI Web Server Gateway Interface

Page 5: Webフレームワークを作ってる話 #osakapy

WSGI??

• Pythonで作るWebアプリケーションの実装方法の標準化仕様

• 実装を切り離して、WebサーバとWAFの組み合わせを柔軟に

https://www.python.org/dev/peps/pep-3333/

https://www.python.org/dev/peps/pep-333/

Page 6: Webフレームワークを作ってる話 #osakapy

WSGI v1.0.1 (PEP3333)

• 2つの引数を持った呼び出し可能なオブジェクト

• 第2引数として渡されたオブジェクトにHTTPステータスコードと (header_name, header_value) タプルのリストを渡す

• 返り値はバイト文字列を yield する iterableなオブジェクト

https://www.python.org/dev/peps/pep-3333/

Page 7: Webフレームワークを作ってる話 #osakapy

WSGI v1.0.1 (PEP3333)

def app(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello World"]

• 2つの引数を持った呼び出し可能なオブジェクト

https://www.python.org/dev/peps/pep-3333/

Page 8: Webフレームワークを作ってる話 #osakapy

WSGI v1.0.1 (PEP3333)

def app(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello World"]

• 第2引数として渡されたオブジェクトの引数はHTTPステータスコードと(header_name, header_value) タプルのリスト

https://www.python.org/dev/peps/pep-3333/

Page 9: Webフレームワークを作ってる話 #osakapy

WSGI v1.0.1 (PEP3333)

def app(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello World"]

• バイト文字列を yield する iterable を返さなければならない

• 例えば、バイト文字列のリストを返すようにする

https://www.python.org/dev/peps/pep-3333/

Page 10: Webフレームワークを作ってる話 #osakapy

Hello World with gunicorn

$ gunicorn -w 1 main:app[2016-04-15 10:17:00 +0900] [1873] [INFO] Starting gunicorn 19.4.5[2016-04-15 10:17:00 +0900] [1873] [INFO] Listening at: http://127.0.0.1:8000 (1873)[2016-04-15 10:17:00 +0900] [1873] [INFO] Using worker: sync[2016-04-15 10:17:00 +0900] [1878] [INFO] Booting worker with pid: 1878^C[2016-04-15 10:17:08 +0900] [1873] [INFO] Handling signal: int[2016-04-15 10:17:08 +0900] [1878] [INFO] Worker exiting (pid: 1878)[2016-04-15 10:17:08 +0900] [1873] [INFO] Shutting down: Master

def app(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello World"]

Page 11: Webフレームワークを作ってる話 #osakapy

Hello World with wsgiref

$ python main.py127.0.0.1 - - [15/Apr/2016 10:24:21] "GET / HTTP/1.1" 200 11127.0.0.1 - - [15/Apr/2016 10:24:21] "GET /favicon.ico HTTP/1.1" 200 11

def app(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello World"]if __name__ == '__main__': from wsgiref.simple_server import make_server httpd = make_server('', 8080, app) httpd.serve_forever()

Page 12: Webフレームワークを作ってる話 #osakapy

WAFで欲しい機能を考える

Page 13: Webフレームワークを作ってる話 #osakapy

最低限欲しい機能• ルーティング

• どこにアクセスしても Hello World

• HTMLテンプレート

• 今はplain text返してるだけ

• Jinja2のTemplate Loaderを用意

Page 14: Webフレームワークを作ってる話 #osakapy

最低限欲しい機能• 静的ファイルをいい感じに返す機能

• 本番だとNginxとか使うけど、開発中は...

• リクエスト・レスポンスオブジェクト

• リクエスト情報はenvが渡されてるけど、ただのdictなのでうまくパースしてほしい

• ステータスとかヘッダ情報をコントロール

Page 15: Webフレームワークを作ってる話 #osakapy

a small and statically-typed web framework

kobinhttps://github.com/c-bata/kobin

Page 16: Webフレームワークを作ってる話 #osakapy

a small and statically-typed web framework

kobinhttps://github.com/c-bata/kobin

Page 17: Webフレームワークを作ってる話 #osakapy

Hello World

from kobin import Kobinapp = Kobin()

@app.route('^/(?P<name>\w*)$')def hello(name: str): return "Hello {}!!".format(name)

if __name__ == '__main__': app.run()

• 日本語: https://kobin.readthedocs.org/ja/latest/ • English: https://kobin.readthedocs.org/en/latest/

Page 18: Webフレームワークを作ってる話 #osakapy

Hello World with Jinja2

import osfrom kobin import Kobin, template

app = Kobin()

@app.route('^/$')def index(): return template('index')

• https://github.com/c-bata/kobin-example • https://kobin.herokuapp.com/

Page 19: Webフレームワークを作ってる話 #osakapy

特徴

• Type Hintsの活用

• Bottleのコードを読んでる時に結構混乱

• mypy 使いたい

• ルーティングへの活用

Page 20: Webフレームワークを作ってる話 #osakapy

Routing in Django

from django.conf.urls import url

urlpatterns = [ url(r'^blog/page(?P<num>[0-9]+)/$', page),]

def page(request, num="1"): # Output the appropriate page of blog entries ...

https://docs.djangoproject.com/en/1.9/topics/http/urls/

• 引数が全て文字列

Page 21: Webフレームワークを作ってる話 #osakapy

Routing in Bottle

from bottle import route

@route('/object/<id:int>')def callback(id): assert isinstance(id, int)

http://bottlepy.org/docs/dev/tutorial.html#request-routing

• 独自DSL

• 型が分かるため、view関数には型変換したオブジェクトを渡すことができる

Page 22: Webフレームワークを作ってる話 #osakapy

ルーティングに対する考察

• 正規表現ベース (Django等)

• 自由度は高い

• 型情報を取得出来ない

• 独自DSL (Bottle, Flask等)

• 自由度は低い

• 型情報を自由に付けれる

Page 23: Webフレームワークを作ってる話 #osakapy

Routing in Kobin

from kobin import Kobinapp = Kobin()

@app.route('^/years/(?P<year>\d{4})$')def casted_year( year: int ): return 'A "year" argument is integer? : {}’ \ .format(isinstance(year, int))

https://github.com/c-bata/kobin/blob/master/example/hello_world.py

• 正規表現により自由度が高い • Type Hintsの恩恵(IDE, mypy)をそのまま受けれる

Page 24: Webフレームワークを作ってる話 #osakapy

Ecosystem Threats to Python

• Pythonのエコシステムはその巨大さゆえに、バージョンアップについていきづらい

• コミュニティとしてもPython3に移行していきたい

• Type Hintsを移行のきっかけに

PyCon APAC/Taiwan 2015: Keynote

Page 25: Webフレームワークを作ってる話 #osakapy

References

• Documentations

• https://kobin.readthedocs.org/ja/latest/

• https://kobin.readthedocs.org/en/latest/

• Kobin Example

• https://github.com/c-bata/kobin-example

• https://kobin.herokuapp.com/

Page 26: Webフレームワークを作ってる話 #osakapy

おまけ PEP333とPEP3333

Page 27: Webフレームワークを作ってる話 #osakapy

PEP333 と PEP3333

$ python2.7>>> b'hoge' + u'日本語'u'hoge\u65e5\u672c\u8a9e'

$ python3.5>>> b'hoge' + u'日本語'Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can't concat bytes to str

Page 28: Webフレームワークを作ってる話 #osakapy

PEP333 と PEP3333

• PEP333 (WSGI v1.0)

• Python2ではbytesとstrを結合出来たり…

• Python3で文字列の扱いが大きく変わった

• PEP3333 (WSGI v1.0.1)

• 後方互換は保ったまま、文字列の扱いを整備して長年たまってたデファクトの修正案も取り込み

Page 29: Webフレームワークを作ってる話 #osakapy

Thanks!