Python初心者がBottleを使ってみたら案外簡単に動いてくれた


はじめに

自分用メモです、経緯は下記。

  • 1週間前くらいからPython始めて、サーバで何か動かしてみたくなった。
  • Webフレームワークの種類を調べてみた。
    • Djangoが一番人気というか間違いないっぽい、けど初心者には少しハードル高そう。
    • いきなり挫折したくないので、とりあえず初心者向けっぽいBottleを選択。

実行環境

  • OS X 10.9.5
  • python 3.5.1
  • PyCharm Community Edition 2016.1.2

やりたいこと

  • とりあえず動かしてみる。
  • ダイナミックなルーティングをしてみる
    • 受け取ったパラメータを利用する
    • パラメータに制約を与える
  • GET, POSTしてみる
  • エラーページを表示してみる

やったこと

とりあえず動かしてみる。

難しいことは考えず、まずはブラウザでHello Worldが表示されるところまでやってみる。

#importするためにpip installしておく
$ pip install bottle
# -*- coding:utf-8 -*-

from bottle import route, run


@route('/hello')
def hello():
    return "Hello World!"


run(host='localhost', port=8080, debug=True)

PyCharmでRunして、ブラウザで開いてみる。
http://localhost:8080/hello

これだけでHello Worldがブラウザで見られるようになった!!すごいなBottle

ダイナミックなルーティングをしてみる

# -*- coding:utf-8 -*-

from bottle import route, run


@route('/hello/')
@route('/hello/<user>')
def hello(user="taro"):
    return "Hello {user}".format(user=user)


@route('/date/<month:re:[a-z]+>/<day:int>/<path:path>')
def date(month, day, path):
    return "{month}/{day} {path}".format(month=month, day=day, path=path)


run(host='localhost', port=8080, debug=True)

受け取ったパラメータを利用する

実行されるメソッドの引数にデフォルトを定義しておくことでuserが渡されない時にも表示できる。
http://localhost:8080/hello/

http://localhost:8080/hello/masaibar

パラメータに制約を与える

簡単な値の制約を与えることが出来る。

  • re 正規表現
  • int int値
  • path /をパスの一部として認識してくれる

http://localhost:8080/date/april/29//dev/null

GET, POSTしてみる

GETやPOSTなどのアノテーションには2種類の書き方があるらしい。
@get('/hoge') と @route('/hoge', method='GET') は同じ動作をする。

渡された値は下記の変数を参照して受け取る。

  • GETリクエストの場合はrequest.query
  • POSTリクエストの場合はrequest.forms

他にもヘッダやリクエスト本文などいろいろなデータを受け取ることが出来る。参考

# -*- coding:utf-8 -*-

from bottle import route, run
from bottle import get, post, request


@route('/login', method='GET')  # or @get('/login')
def login():
    username = request.query.get('user')
    password = request.query.get('pass')

    #GETで何も渡されていない時はusername,passwordに何も入れない
    username = "" if username is None else username
    password = "" if password is None else password

    return '''
    <form action="/login" method="post">
            Username: <input name="username" type="text" value="{username}"/>
            Password: <input name="password" type="password" value="{password}"/>
            <input value="Login" type="submit" />
        </form>
    '''.format(username=username, password=password)


@route('/login', method='POST')  # or @post('/post')
def do_login():
    username = request.forms.get('username')
    password = request.forms.get('password')

    return "{username} {password}".format(username=username, password=password)


run(host='localhost', port=8080, debug=True)

GET

http://localhost:8080/login

http://localhost:8080/login?user=hoge&pass=fuga

POST

エラーページを表示してみる

# -*- coding:utf-8 -*-

from bottle import route, run
from bottle import error


@route('/hello')
def hello():
    return "Hello World!"


@error(404)
def error404(error):
    return "Nothing here sorry {error}".format(error=error)


run(host='localhost', port=8080, debug=True)

わざと有りもしないURLを踏んでみる。
http://localhost:8080/hellow

おわりに

思ったよりも簡単に動いてくれて正直驚きました。
今回は特にテンプレートとか考えないで動かすことに重きを置いていましたが、調べてみるとテンプレートエンジンだけ差し替えて使っている人が結構いる感じでした。
(Jinja2が人気なのかな?)

参考

Tutorial — Bottle 0.13-dev documentation : http://bottlepy.org/docs/dev/tutorial.html
PythonのWebフレームワーク6種をかんたんに紹介 - モジログ : http://mojix.org/2013/04/13/python-six-wafs
BottleのRequest/Responseオブジェクトをマスター - Qiita : http://qiita.com/tomotaka_ito/items/62fc4d58d1be7867a158
PythonではNoneの比較は==ではなくisを使う - こんにちはこんにちはmonmonです! : http://monmon.hateblo.jp/entry/20110214/1297710749