Bottle

Ole Martin Bjørndalen

29. November 2013

http://bottlepy.org/

(Press "a" for slide view.)

Bottle

Hello World

from bottle import route, run

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

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

Routing

@get('/food')

@post('/food')

@route('/food', method='GET')

@route('/food')
def food():
    if request.method == 'GET':
        ...

Templates

from bottle import template

@get('/hello/<name>')
def hello(name='World'):
    return template('hello_template', name=name)

This renders template.tpl (from bottle.TEMPLATE_PATH).

View Decorator

@get('/hello/<name>')
@view('hello_template')
def hello(name='World'):
    return dict(name=name)

Request / Response

from bottle import request, response

@get('/food')
def food():
    cookie = request.get_cookie()
    ...
    response.content_type = 'text/html'
    response.charset = 'latin9'

Query

http://moviedb/search?title=King+Kong
@get('/search')
def movie_search():
    title = request.query.title
    if title == 'King Kong':
        ...

Default value is an empty string.

Forms

@get('/login')
def login():
    ...

@post('/login')
def login():
    username = request.forms.get('username')
    password = request.forms.get('password')
    if check_login(username, password):
        ...

(Or WTForms)

Static Files

from bottle import static_file

@route('/static/<filepath:path>')
def server_static(filepath):
    return static_file(filepath,
           root='/path/to/your/static/files')

Error!

from bottle import error

@error(404)
def error404(error):
    return 'Nothing here, sorry'

JSON

@get('/food')
def food():
    # Dict is automatically converted to JSON.
    return {'type': 'Pizza', 'price': 'Free'}

@post('/service')
def service():
    data = request.json
    ...

App

app = Bottle()

@app.get('/')
def hello():
    return 'Hello World'

parent_app = bottle.default_app()
parent_app.mount("/hello", app)

For larger applications and reusability.

Running the App

import bottle

if __name__ == '__main__':
    # Standalone web server
    bottle.run()
else:
    # Running under another web server (with WSGI)
    application = bottle.default_app()

Apache Config

WSGIDaemonProcess yourapp \
    user=www-data group=www-data \
    processes=1 threads=5
WSGIScriptAlias /ole/bottle /path/to/server.py

Debug og Auto Reloading

bottle.debug(True)
bottle.run(reloader=True)

(Standalone server only.)

Useful Additions

(Of course, no longer one file.)

JSON-RPC

import bottle_jsonrpc

class Methods:
    def add(self, a, b):
        return a + b

bottle_jsonrpc.register('/math', Methods())

http://github.com/olemb/bottle_jsonrpc

Flask

Much the same, but based on Werkzeug og Jinja2.

from flask import Flask
app = Flask(__name__)

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

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

importd

Wrapper around Django.

from importd import d

@d('/')
def idx(request):
    return 'index.html'

if __name__ == '__main__':
    d.main()

The End

$ pip install bottle

http://bottlepy.org/