Python Notes and Examples

Web Development

Have a look at Django or Flask.

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

Bottle

To create a bottle webapp, start with:

mkdir my-webapp
cd my-webapp
wget http://bottlepy.org/bottle.py  # Directly gets the very latest bottle.
touch main.py
chmod +x main.py

Make main.py 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__)

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

Run that (./main.py), 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 bottle.run(…) until you Ctrl-C to stop the webapp. bottle.run 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: http://bottlepy.org/docs/dev/tutorial.html.
See also: http://www.fullstackpython.com/bottle.html.

Bigger example

#!/usr/bin/env python3

import bottle

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

html_tail = '''</body>
</html>
'''

@bottle.route('/login')
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" />
</form>
''' + 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

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

Notes about routing

@bottle.route('/<foo>')
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:

@bottle.route('/')
@bottle.route('/foo')
def root_or_foo():
    #...

You can use a “filtered” wildcard like so:

@bottle.route('/id-num/<id_num:int>')
def show_by_id(id_num):
    # `id_num` is an int.