Tutorial: Getting started with Bottle – a Python web framework

Post to Twitter

According to the Bottle website: “Bottle is a fast, simple and lightweight WSGI micro web-framework for Python“. According to their Twitter page Bottle originates from Goettingen, Germany (incidently, a lot of German folks follow this blog). At first look you might compare Bottle to Sinatra or Express. I’ll be using PyCharm and Python 2.7.1 on OS X to build these examples but it should work equally well on Windows and Linux with minimal modifications if any.


Create a folder to hold the sample files. Inside the folder create a file called app.py. Grab the development (unstable) copy of bottle.py from here and put it into the same folder as the app.py file (One nice thing about Bottle is that it has no other dependencies other than the Python library). You can also grab the stable version if you want to install Bottle you can by following the docs here.

I’ll borrow the first example from the Bottle website. With the two files ready, go into the app.py file and add the following:

from bottle import route, run

@route('/hello/:name')
def index(name='World'):
    return '<strong>Hello %s!</strong>' % name

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

Run the app.py file.

$ python app.py

Expected output:

Bottle v0.11.dev server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

Go to the following URL with a web browser: http://localhost:8080/hello/world

You should get a Hello World message back from the browser.

The code is pretty simple. We setup the route and allow a value that you can set. The server listens on localhost at port 8080.

Let’s try something else involving dynamic routes.

from bottle import route, run

@route('/<unknown>')
def default(unknown):
    return '<strong>Unknown: %s</strong>' % unknown

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

Go to the following URL with a web browser: http://localhost:8080/dynamic

We can even use more than one dynamic route:

from bottle import route, run

@route('/<path1>/<path2>')
def default(path1, path2):
    return '<strong>Path 1: %(path1)s<br />Path 2: %(path2)s</strong>' % {"path1": path1, "path2": path2}

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

Go to the following URL with a web browser: http://localhost:8080/p1/p2

Expected output:

Path 1: p1
Path 2: p2

You can also easily support HTTP Verbs like GET, POST, PUT, and DELETE by adding a second parameter to route:

from bottle import route, run

@route('/hello', method='GET')
def default():
    return '<strong>GET on /hello was called</strong>'

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

The above code will only answer to HTTP GET at the following URL: http://localhost:8080/hello

Expected output:

GET on /hello was called

To only answer to HTTP POST then use the following:

from bottle import route, run

@route('/hello', method='POST')
def default():
    return '<strong>POST on /hello was called</strong>'

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

You can test that code easily using curl or a browser plugin like XHR Poster (for Chrome).

This is only the tip of the iceberg of what Bottle can do. You can use templates, serve static files and a ton more.

You can follow the BottlePy team on Twitter and check out the community on their Google Group.

Post to Twitter

This entry was posted in Python. Bookmark the permalink.

One Response to Tutorial: Getting started with Bottle – a Python web framework

  1. E says:

    Thanks for this post. I am learning Python and naturally am looking for a web framework. However, I am looking for a ‘micro’ framework with little to no ‘magic’.

    Comment on the above: I would add a couple of expected lines, like for the ‘Dynamic’ example… there is no expected output given.

    Question: What is your experience using Bottle in production? Have you experienced easier setup in any server setup vs another?

Comments are closed.