bottleソースコードリーディング その1
webフレームワークのソースコードリーディングの記録です。
Djangoは量が多いのでまずは軽量フレームワークのbottleのソースコードを読んでみました。
サンプルコード
from bottle import route, run, template
@route('/hello/<name>')
def index(name):
return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)
ルーティングの登録
まず、デコレータrouteが実行され、indexメソッドが登録される
importされているrouteは以下
make_default_app_wrapperでは、Bottleクラスから引数のメソッドを取得しているので
(L3182のapp()でBottleオブジェクト取得している)
Bottleクラス内で定義されているrouteが実行される
L918のelseのdecoratorが実行され、add_routeにて、ルートのパターンと関数が登録される
L867のaddの処理で登録
add内の最終行で_compileが実行され、そこでself.dyna_regexesにルーティングのルールとindexメソッドのデータが追加される(ここの細かい内容についてはまだ未確認)
ここまででルーティングのルールが登録される。
サーバー起動
ルーティング登録後、runでサーバーが起動される
from bottle import route, run, template
@route('/hello/<name>')
def index(name):
return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)
サーバーはデフォルト引数からポートやBottleオブジェクトを引数として渡してwsgirefサーバーが起動する(L3725のserver.run(app))
※ここは細かく見ないがcpythonのwsgirefサーバーが起動するリクエストの処理
※ここでは、localhost:8080/hello/yamadaにアクセスしたとします
Bottleの__call__()がリクエスト時に呼び出される
_handleメソッド内にてmatchが実行され、リクエストの情報からレスポンスを生成するために必要なデータを取り出す
このmatchでは、登録した情報(indexメソッドなど)が入ったRouteオブジェクトとリクエストに含まれる引数のデータがかえってくる(この場合、{'name': 'yamada'})
L983にて取得したリクエストのデータを引数にRouteオブジェクトのcallメソッドが実行される
callメソッドではRouteオブジェクト内のcallbackが返されるので、ここではindexメソッドが返ってきて、リクエストのデータ({'name': 'yamada'})を引数に、indexメソッドが実行される
生成されたhtml用の文字列がiterableな型でwsgiサーバーへと返される
Discussion