SlideShare a Scribd company logo
WAFをつくってる話
大阪Pythonユーザの集まり 2016/04
MASASHI SHIBATA
! c_bata_
@c_bata_
django / flask / pandas
明石高専
話すこと
1. WSGIの話とか
2. WAFに欲しい機能を考える
3. Kobinの紹介
4. Kobinにおける取り組み
WSGI
Web Server Gateway Interface
WSGI??
• Pythonで作るWebアプリケーションの実装方
法の標準化仕様
• 実装を切り離して、WebサーバとWAFの組み
合わせを柔軟に
https://www.python.org/dev/peps/pep-3333/
https://www.python.org/dev/peps/pep-333/
WSGI v1.0.1 (PEP3333)
• 2つの引数を持った呼び出し可能なオブジェクト
• 第2引数として渡されたオブジェクトにHTTPス
テータスコードと (header_name,
header_value) タプルのリストを渡す
• 返り値はバイト文字列を yield する iterableなオ
ブジェクト
https://www.python.org/dev/peps/pep-3333/
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/
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/
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/
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"]
Hello World with wsgiref
$ python main.py
127.0.0.1 - - [15/Apr/2016 10:24:21] "GET / HTTP/1.1" 200 11
127.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()
WAFで欲しい機能を考える
最低限欲しい機能
• ルーティング
• どこにアクセスしても Hello World
• HTMLテンプレート
• 今はplain text返してるだけ
• Jinja2のTemplate Loaderを用意
最低限欲しい機能
• 静的ファイルをいい感じに返す機能
• 本番だとNginxとか使うけど、開発中は...
• リクエスト・レスポンスオブジェクト
• リクエスト情報はenvが渡されてるけど、

ただのdictなのでうまくパースしてほしい
• ステータスとかヘッダ情報をコントロール
a small and statically-typed web framework
kobin
https://github.com/c-bata/kobin
a small and statically-typed web framework
kobin
https://github.com/c-bata/kobin
Hello World
from kobin import Kobin
app = 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/
Hello World with Jinja2
import os
from kobin import Kobin, template
app = Kobin()
@app.route('^/$')
def index():
return template('index')
• https://github.com/c-bata/kobin-example
• https://kobin.herokuapp.com/
特徴
• Type Hintsの活用
• Bottleのコードを読んでる時に結構混乱
• mypy 使いたい
• ルーティングへの活用
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/
• 引数が全て文字列
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関数には型変換したオブジェ
クトを渡すことができる
ルーティングに対する考察
• 正規表現ベース (Django等)
• 自由度は高い
• 型情報を取得出来ない
• 独自DSL (Bottle, Flask等)
• 自由度は低い
• 型情報を自由に付けれる
Routing in Kobin
from kobin import Kobin
app = 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)をそのまま受けれる
Ecosystem Threats to Python
• Pythonのエコシステムはその巨大さゆえに、バー
ジョンアップについていきづらい
• コミュニティとしてもPython3に移行していきたい
• Type Hintsを移行のきっかけに
PyCon APAC/Taiwan 2015: Keynote
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/
おまけ
PEP333とPEP3333
PEP333 と PEP3333
$ python2.7
>>> b'hoge' + u'日本語'
u'hogeu65e5u672cu8a9e'
$ python3.5
>>> b'hoge' + u'日本語'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to str
PEP333 と PEP3333
• PEP333 (WSGI v1.0)
• Python2ではbytesとstrを結合出来たり…
• Python3で文字列の扱いが大きく変わった
• PEP3333 (WSGI v1.0.1)
• 後方互換は保ったまま、文字列の扱いを整備して
長年たまってたデファクトの修正案も取り込み
Thanks!

More Related Content

PPTX
Robot Framework (のSelenium2Libraryのお話)
PDF
Werkzeugを使ってみた #osakapy 2016/04
PPTX
Taming robotframework
PPTX
Re: WebServer BenchMarking
PDF
PHPとJavaScriptの噺
PDF
恋に落ちるデプロイツール
PDF
minneで学ぶクラウド脳
PDF
PHPデプロイツールの世界
Robot Framework (のSelenium2Libraryのお話)
Werkzeugを使ってみた #osakapy 2016/04
Taming robotframework
Re: WebServer BenchMarking
PHPとJavaScriptの噺
恋に落ちるデプロイツール
minneで学ぶクラウド脳
PHPデプロイツールの世界

What's hot (20)

PDF
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
PPTX
イベント駆動プログラミングとI/O多重化
PPTX
PHP x AWS でスケーラブルなシステムをつくろう
PDF
NorikraのJVMチューンで苦労している話
PDF
Haikara
PDF
Java による Web アプリケーションのプロトタイプのために最近使っている構成
PDF
ChefとPuppetの比較
PDF
chat bot framework for Java8
PDF
apachehereというPHPのBuiltin Serverっぽいやつをつくった
PDF
Closure Compiler Updates for ES6
PPTX
明日から始める Chef 入門 #bpstudy
PDF
Puppet on AWS
PDF
Real World PHP in pixiv
PDF
Djangoフレームワークの紹介 OSC2015北海道
PDF
仮想マシンを使った開発環境の簡単共有方法
PDF
MogileFS をバックエンドとしたPrivate S3の作り方 【後半】API 編
KEY
Composer
PDF
いまどきのPHP開発現場 -2015年秋-
PDF
誰でも出来るローカル開発環境の作り方
PPTX
わんくま東京#46 予告編
Web Framework Benchmarksと Perl の現状報告会 YAPC::Asia Tokyo 2014 LT
イベント駆動プログラミングとI/O多重化
PHP x AWS でスケーラブルなシステムをつくろう
NorikraのJVMチューンで苦労している話
Haikara
Java による Web アプリケーションのプロトタイプのために最近使っている構成
ChefとPuppetの比較
chat bot framework for Java8
apachehereというPHPのBuiltin Serverっぽいやつをつくった
Closure Compiler Updates for ES6
明日から始める Chef 入門 #bpstudy
Puppet on AWS
Real World PHP in pixiv
Djangoフレームワークの紹介 OSC2015北海道
仮想マシンを使った開発環境の簡単共有方法
MogileFS をバックエンドとしたPrivate S3の作り方 【後半】API 編
Composer
いまどきのPHP開発現場 -2015年秋-
誰でも出来るローカル開発環境の作り方
わんくま東京#46 予告編
Ad

Viewers also liked (20)

PDF
Introduction of Feedy
PDF
Goji とレイヤ化アーキテクチャ
PDF
Pyconjp2016 pyftplib
PDF
幾個曾經 發生在數位系的小故事
PDF
RaspberryPiで日本の子供たちにプログラミングのパッションを伝えよう!
PDF
Python入門 コードリーディング - PyConJP2016
PDF
Robot framework association intro
PDF
利用 Appium + Robot Framework 實現跨平台 App 互動測試
PDF
Pythonで実現する4コマ漫画の分析・評論
PDF
4コマ漫画 Machine Learning 分析データを集めたかった話
PPTX
Web testing automation
PDF
Python入門
PDF
開放資料與 Drupal
PPTX
Entity framework + Linq 介紹
PDF
並行與平行
PDF
ATDD Using Robot Framework
PDF
JavaCro'14 - Test Automation using RobotFramework Libraries – Stojan Peshov
PDF
Functional Tests Automation with Robot Framework
PDF
Frontend django, Django Web 前端探索
PDF
Rails Girls Weekly - 初探前端網頁技術 JavaScript 3/3
Introduction of Feedy
Goji とレイヤ化アーキテクチャ
Pyconjp2016 pyftplib
幾個曾經 發生在數位系的小故事
RaspberryPiで日本の子供たちにプログラミングのパッションを伝えよう!
Python入門 コードリーディング - PyConJP2016
Robot framework association intro
利用 Appium + Robot Framework 實現跨平台 App 互動測試
Pythonで実現する4コマ漫画の分析・評論
4コマ漫画 Machine Learning 分析データを集めたかった話
Web testing automation
Python入門
開放資料與 Drupal
Entity framework + Linq 介紹
並行與平行
ATDD Using Robot Framework
JavaCro'14 - Test Automation using RobotFramework Libraries – Stojan Peshov
Functional Tests Automation with Robot Framework
Frontend django, Django Web 前端探索
Rails Girls Weekly - 初探前端網頁技術 JavaScript 3/3
Ad

Similar to Webフレームワークを作ってる話 #osakapy (20)

PDF
Backlogでの Perlのつかいかた
PPTX
HTML5&API総まくり
PPTX
HTML5最新動向
PPTX
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
PDF
Python × Herokuで作る 雑談slack bot
PDF
近頃のDockerネットワーク
PDF
KotlinConf 2018 から見る 最近の Kotlin サーバーサイド事情
PDF
GitLab から GitHub + CircleCI に乗り換えてチーム運用を改善しつつある話
 
PDF
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
PDF
[Japan Tech summit 2017] DEP 005
PDF
Isomorphic web development with scala and scala.js
PDF
はてなにおける継続的デプロイメントの現状と Docker の導入
PDF
How to run P4 BMv2
KEY
Composer による依存管理 と Packagist によるライブラリの公開
PDF
Jjug springセッション
PDF
Observability, Service Mesh and Microservices
PPTX
AKS (k8s) Hands on Lab Contents
PPTX
2012 0623-x-road-tokyo-xoops-x(ten)
PDF
RESTful Webサービス
PPTX
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Backlogでの Perlのつかいかた
HTML5&API総まくり
HTML5最新動向
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
Python × Herokuで作る 雑談slack bot
近頃のDockerネットワーク
KotlinConf 2018 から見る 最近の Kotlin サーバーサイド事情
GitLab から GitHub + CircleCI に乗り換えてチーム運用を改善しつつある話
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
[Japan Tech summit 2017] DEP 005
Isomorphic web development with scala and scala.js
はてなにおける継続的デプロイメントの現状と Docker の導入
How to run P4 BMv2
Composer による依存管理 と Packagist によるライブラリの公開
Jjug springセッション
Observability, Service Mesh and Microservices
AKS (k8s) Hands on Lab Contents
2012 0623-x-road-tokyo-xoops-x(ten)
RESTful Webサービス
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」

More from Masashi Shibata (20)

PDF
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
PDF
実践Djangoの読み方 - みんなのPython勉強会 #72
PDF
CMA-ESサンプラーによるハイパーパラメータ最適化 at Optuna Meetup #1
PDF
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
PDF
Implementing sobol's quasirandom sequence generator
PDF
DARTS: Differentiable Architecture Search at 社内論文読み会
PDF
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
PDF
PythonとAutoML at PyConJP 2019
PDF
Djangoアプリのデプロイに関するプラクティス / Deploy django application
PDF
Django REST Framework における API 実装プラクティス | PyCon JP 2018
PDF
Django の認証処理実装パターン / Django Authentication Patterns
PDF
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
PDF
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
PDF
Golangにおける端末制御 リッチなターミナルUIの実現方法
PDF
How to develop a rich terminal UI application
PDF
Pythonのすすめ
PDF
pandasによるデータ加工時の注意点やライブラリの話
PDF
Pythonistaのためのデータ分析入門 - C4K Meetup #3
PDF
テスト駆動開発入門 - C4K Meetup#2
PDF
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015
MLOps Case Studies: Building fast, scalable, and high-accuracy ML systems at ...
実践Djangoの読み方 - みんなのPython勉強会 #72
CMA-ESサンプラーによるハイパーパラメータ最適化 at Optuna Meetup #1
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
Implementing sobol's quasirandom sequence generator
DARTS: Differentiable Architecture Search at 社内論文読み会
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
PythonとAutoML at PyConJP 2019
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Django REST Framework における API 実装プラクティス | PyCon JP 2018
Django の認証処理実装パターン / Django Authentication Patterns
RTMPのはなし - RTMP1.0の仕様とコンセプト / Concepts and Specification of RTMP
システムコールトレーサーの動作原理と実装 (Writing system call tracer for Linux/x86)
Golangにおける端末制御 リッチなターミナルUIの実現方法
How to develop a rich terminal UI application
Pythonのすすめ
pandasによるデータ加工時の注意点やライブラリの話
Pythonistaのためのデータ分析入門 - C4K Meetup #3
テスト駆動開発入門 - C4K Meetup#2
Introduction of PyCon JP 2015 at PyCon APAC/Taiwan 2015

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

  • 2. @c_bata_ django / flask / pandas 明石高専
  • 3. 話すこと 1. WSGIの話とか 2. WAFに欲しい機能を考える 3. Kobinの紹介 4. Kobinにおける取り組み
  • 6. WSGI v1.0.1 (PEP3333) • 2つの引数を持った呼び出し可能なオブジェクト • 第2引数として渡されたオブジェクトにHTTPス テータスコードと (header_name, header_value) タプルのリストを渡す • 返り値はバイト文字列を yield する iterableなオ ブジェクト https://www.python.org/dev/peps/pep-3333/
  • 7. 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/
  • 8. 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/
  • 9. 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/
  • 10. 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"]
  • 11. Hello World with wsgiref $ python main.py 127.0.0.1 - - [15/Apr/2016 10:24:21] "GET / HTTP/1.1" 200 11 127.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()
  • 13. 最低限欲しい機能 • ルーティング • どこにアクセスしても Hello World • HTMLテンプレート • 今はplain text返してるだけ • Jinja2のTemplate Loaderを用意
  • 14. 最低限欲しい機能 • 静的ファイルをいい感じに返す機能 • 本番だとNginxとか使うけど、開発中は... • リクエスト・レスポンスオブジェクト • リクエスト情報はenvが渡されてるけど、
 ただのdictなのでうまくパースしてほしい • ステータスとかヘッダ情報をコントロール
  • 15. a small and statically-typed web framework kobin https://github.com/c-bata/kobin
  • 16. a small and statically-typed web framework kobin https://github.com/c-bata/kobin
  • 17. Hello World from kobin import Kobin app = 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/
  • 18. Hello World with Jinja2 import os from kobin import Kobin, template app = Kobin() @app.route('^/$') def index(): return template('index') • https://github.com/c-bata/kobin-example • https://kobin.herokuapp.com/
  • 19. 特徴 • Type Hintsの活用 • Bottleのコードを読んでる時に結構混乱 • mypy 使いたい • ルーティングへの活用
  • 20. 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/ • 引数が全て文字列
  • 21. 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関数には型変換したオブジェ クトを渡すことができる
  • 22. ルーティングに対する考察 • 正規表現ベース (Django等) • 自由度は高い • 型情報を取得出来ない • 独自DSL (Bottle, Flask等) • 自由度は低い • 型情報を自由に付けれる
  • 23. Routing in Kobin from kobin import Kobin app = 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)をそのまま受けれる
  • 24. Ecosystem Threats to Python • Pythonのエコシステムはその巨大さゆえに、バー ジョンアップについていきづらい • コミュニティとしてもPython3に移行していきたい • Type Hintsを移行のきっかけに PyCon APAC/Taiwan 2015: Keynote
  • 25. 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/
  • 27. PEP333 と PEP3333 $ python2.7 >>> b'hoge' + u'日本語' u'hogeu65e5u672cu8a9e' $ python3.5 >>> b'hoge' + u'日本語' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't concat bytes to str
  • 28. PEP333 と PEP3333 • PEP333 (WSGI v1.0) • Python2ではbytesとstrを結合出来たり… • Python3で文字列の扱いが大きく変わった • PEP3333 (WSGI v1.0.1) • 後方互換は保ったまま、文字列の扱いを整備して 長年たまってたデファクトの修正案も取り込み