藻ログ

都会でOLをしています

bottles

Lightweight WAF

例えばデモ用などに小規模なWebアプリケーションを作りたいとき,そんなに多くの機能を備えたフレームワークは必要ありません.とはいえ,例えばpythonなら標準ライブラリの CGIHTTPServer で頑張るのもちょっと辛いものがあります*1.
そこで軽量フレームワークとして最近*2人気らしいBottleを使ってみました.
bottlepy.org

他の選択肢としては,昔からあるCherryPyとかでしょうか.
CherryPy — A Minimalist Python Web Framework

Quick start

Bottleは1ファイルでのみ構成されている非常にシンプルなフレームワークです.
なので何かあれば site-packages/bottle.py を読めば良いです.

$ pip install bottle

sourcetree

templateの検索パスを探ると,デフォルトがTEMPLATE_PATH=['./', './views/'] のようになっていたのでとりあえず以下のような構成にしてみた.

app.py
├── lib
│   ├── api.py
├── static
│   ├── js
│         ├── main.js
│   ├── css
│         ├── main.css
├── views
│   ├── index.tpl

app.py

static/以下を静的ファイル置き場にするため,そこにもルーティングしといた.

from bottle import get, run, template, static_file

@route("/static/<filepath:path>", name="static_file")
def static(filepath):
    return static_file(filepath, root="./static")

@get('/')
def index():
    return template('index', text="hello, world")

run(host='localhost', port=8000)

index.tpl

テンプレートエンジンもシンプルで使いやすそう.
SimpleTemplate Engine — Bottle 0.13-dev documentation

<html>
  <head>
    <title>test</title>
    <link rel="stylesheet" href="static/css/main.css">
    <script type="text/javascript" src="static/js/main.js"></script>
  </head>
  <body>
     {{text}}
  </body>
</html>

python app.py で起動し,localhost:8000にアクセスすれば動作が確認できます.

リモートホストからアクセスする場合

run(host='XXX.XX.XX.XX', port=8000)

でXXXを自身の固定IPにすれば ${ip}:8000みたいな感じでよそのPCからアクセスできます.

デバッグ

tracebackとオートリロード

debug=Trueにしておくとエラーページでtracebackが出ます.
また,reloader=Trueにしておくとソース変更時にオートリロードしてくれるので,一々サーバを再起動する必要はありません.

run(host='localhost', port=8000, debug=True, reloader=True)

ダン

適当にstderrに吐いてサーバーログに出してしまってる

print >> sys.stderr, $(data)

GET, POST

routeで引数指定するか,get/postを使うかになります.

from bottle import route, get, post
@route('/' method='GET')
@get('/')

requestとresponse

jsonのやり取りだけちょっとハマったのでメモ.
jsonを送るときはPOSTでrequest.jsonを使うのが良さそうだった.

main.js

var send_data = { foo: bar, hoge: piyo };
$.ajax({ url : '/api/stardust/ol',
         type : 'post',
         contentType : 'application/json',
         dataType : 'json',
         data : JSON.stringify(send_data)
         }).done(function(data){
           console.log(data)
         });

app.py

from bottle import post, request, HTTPResponse
@post("/api/stardust/ol")
def api_test():
    data1 = request.json['foo']
    data2 = request.json['hoge']

    result = api.do_something(data1,data2)

    res = HTTPResponse(status=200)
    res.content_type = 'application/json'
    return json.dumps({'key': result})

その他のクエリパラメータの受け方は以下参照.
Tutorial — Bottle 0.13-dev documentation

Attribute GET Form fields POST Form fields File Uploads
BaseRequest.query yes no no
BaseRequest.forms no yes no
BaseRequest.files no no yes
BaseRequest.params yes yes no

Request Entity Too Large問題

Error: 413 Request Entity Too Large

クライアント側から大きいjsonデータを送りつけると死ぬので,データサイズの大きいjsonをやり取りする場合は
BaseRequest.MEMFILE_MAX =を十分でかい値にして app.pyに書いといてください.

まとめ

今回は個人用のちっちゃいツールを作るのにちょっと触っただけだけど,シンプルで使いやすかった.
フレームワーク本体が1ファイルというのが大きい.SQLitepluginもあるみたいなので,小規模なアプリケーションなら十分まかなえそうな気がする.

*1:でもたまに使う

*2:もう最近じゃないかもしれない