Python Notes and Examples
← prev | next →     Top-level ToC     /web-dev.html     (printable version)

Have a look at Django or Flask.

That said, for a really fast way to get started, Bottle is one file ( You can download it and drop it into your project dir, or else install it via apt.

1 Bottle

To create a bottle webapp, start with:

mkdir my-webapp
cd my-webapp
wget  # Directly gets the very latest bottle.
chmod +x

Make look like:

#!/usr/bin/env python3

import bottle

# Note `method` here is `GET` (the default if you omit `method`).
# You could also use `POST`.
@bottle.route('/hello/<name>', method='GET')  # "`<name>`" is a wildcard.
def index(name):
    return bottle.template('<b>Hello {{name}}</b>! Bottle version {{ver}}',
                           name=name, ver=bottle.__version__)'localhost', port=8080, debug=True)

Run that (./, then point your browser to http://localhost:8080/hello/world.

Pages served will not have any doctype, html, or head tags. We’ll get back to how to include those.

When you run the webapp, you’re in…) until you Ctrl-C to stop the webapp. waits for requests, services them, and waits for the next request.

Bottle handles requests sequentially; the previous request must complete and return a response before the next one is looked at.

Tutorial: See also:

1.1 Bigger example

#!/usr/bin/env python3

import bottle

html_head = '''<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

html_tail = '''</body>

def login():
    return html_head + '''<form action="/login" method="post">
Username: <input name="username" type="text" /> <br/>
Password: <input name="password" type="password" /> <br/>
<input value="Login" type="submit" />
''' + html_tail

@bottle.route('/login', method='POST')
def do_login():
    username = bottle.request.forms.get('username')
    password = bottle.request.forms.get('password')
    return html_head + 'U: ' + username + '<br/>\n' + \
                       'P: ' + password + '<br/><a href="/login">login</a>' + \
                       html_tail'localhost', port=8080, debug=True)

1.2 Notes about routing

def stuff(foo):
    return bottle.template('Hey {{someone}}!', someone=foo)

Terminology: /<foo> is the route, index is the callback.

Bottle passes the value for the wildcard (here, whatever <foo> is) as a keyword arg to the callback.

Routes may or may not end with a trailing slash. Bottle pays attention, and considers them different routes.

Instead of @route, you can use @get or @post (or @put, @delete, @patch). @get(...) == @route(...), and @post == @route('...', method='POST').

If you want, you can bind more than one route to a callback:

def root_or_foo():

You can use a “filtered” wildcard like so:

def show_by_id(id_num):
    # `id_num` is an int.