Bottle: Python Web Framework

Botle Logo

Bottle is a fast and simple WSGI web-framework for Python packed into a single file with no external dependencies.

Core Features

Download / Install

You can install the latest stable release with easy_install -U bottle or just download the newest bottle.py and place it in your project directory. There are no (hard) dependencies other than the Python standard library. Bottle runs with Python 2.5+ and 3.x (using 2to3)

Features and Examples

No installation or configuration required. No dependencies other than the Python standard library. Just get a copy of bottle.py, place it into your project directory and start coding.

1
2
3
4
5
6
7
from bottle import route, run

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

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

That's all. Run your code and visit http://localhost:8080/

Routes

Use the @route() decorator to bind URLs to your handler functions. Named parameters may be used to produce nice looking URLs.

1
2
3
@route('/hello/:name')
def hello(name):
    return 'Hello, %s' % name

Templates

Bottle includes a simple and lightning fast template engine called SimpleTemplate. Just return a dictionary filled with template variables and pass a template name to the @view decorator.

1
2
3
4
5
@route('/hello/template/:names')
@view('hello')
def template_hello(names):
   names = names.split(',')
   return dict(title='Hello World', names=names)

And here is the template in "./views/hello.tpl":

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<html>
 <head>
  <title>{{title}}</title>
 </head>
 <body>
  %for name in names:
    <p>Hello, <strong>{{name}}</strong></p>
  %end
 </body>
</html>

Bottle makes it easy to switch to other template engines. mako, jinja2 and cheetah are supported.

1
from bottle import mako_view as view

Static Files, Redirects and HTTP Errors

Use these handy helpers for regular tasks.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from bottle import send_file, redirect, abort

@route('/static/:filename')
def static_file(filename):
    send_file(filename, root='/path/to/static/files')

@route('/wrong/url')
def wrong():
    redirect("/right/url")

@route('/restricted')
def restricted():
    abort(401, "Sorry, access denied.")

POST, GET, Header and Cookies

As easy as using a dict()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from bottle import request, response

@route('/hello/cookie')
def cookie():
    name = request.COOKIES.get('name', 'Stranger')
    response.header['Content-Type'] = 'text/plain'
    return 'Hello, %s' % name

@route('/hello/cookie', method='POST')
def set_cookie():
    if 'name' in request.POST:
        name = request.POST['name']
        response.COOKIES['name'] = name
    return 'OK'

HTTP Server

Bottle has a HTTP Server build in but also supports cherrypy, flup, paste and fapws3 as alternatives.

1
2
from bottle import PasteServer
run(server=PasteServer)

Non-Features and Known Bugs

Bottle does not include (yet):

Voices

Kaelin, 2009-10-22, PyPi Comment:

Bottle rocks! The fastest path I've found between idea and implementation for simple Web applications.

Seth in his blog posts about common web framework performance:

As you can see, there was practically no difference in speed between Bottle and pure WSGI in a basic “hello world” test. Even with the addition of Mako and SQLAlchemy, Bottle performed significantly faster than a bare Pylons or Django setup. On a side note, adding a sample template using Bottle’s default templating package didn’t seem to change these numbers at all.

Projects using Bottle

Thanks to

In chronological order of their last contribution (DESC).

Licence (MIT)

Copyright (c) 2009, Marcel Hellkamp.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Edit this page at GitHub