Using bottle.py in production

This is a quick guide to using bottle.py in a (semi-)production environment with lighttpd. Bottle.py is a super-lightweight (one source file!) web framework for Python which I use for quick, single-purpose web scripts. For example, I have used Bottle.py for small web applications to:

Monitor CPU and HDD temps

Provide a quick and easy personal file drop location

Administer hg repositories

This guide will show some techniques to write a URL-agnostic app in Bottle.py and then deploy it, using FCGI and lighttpd. Requirements:

python>=2.7

bottle.py>=0.10

flup

Bottle.py tips

get_url

Use the get_url function to write a URL-agnostic app. With get_url , you can mount your app at any root URL on your server. For example, if your app handles the /viewpost and /listposts URLs, and you mount it at http://mywebsite.com/blog/ , the final URLs that you would access from your web browser would be http://mywebsite.com/blog/viewpost and http://mywebsite.com/blog/listposts . You can only use get_url with named routes:

import bottle app = bottle.default_app() @app.route('/viewposts', name='viewposts') def handle_viewposts(): return 'first post!' # Calling get_url from handle_index @app.route('/index') def handle_index(): return '<a href="{}">View posts</a>'.format(app.get_url('viewposts'))

You can also use get_url for dynamic routes (routes with parameters):

@app.route('/get/<name:path>', name='getobj') def handle_getobj(name): return bottle.static_file(name, root='/path/to/files') # Call get_url like this url = app.get_url('getobj', name='filename.txt')

Deploying with flup

Usually I deploy Python web apps with flup (there's also a Python 3 version). I use FastCGI on a Unix socket, running behind lighttpd. For these examples, assume that the app socket is called /run/lighttpd/myapp.sock .

Python configuration

For Python 2.7 and flup, use Bottle's builtin flup server, setting the bindAddress to the path to the socket:

if __name__ == "__main__": run(server='flup', options={'bindAddress': '/run/lighttpd/myapp.sock'})

lighttpd

Make sure mod_fastcgi is loaded in your config. To mount an FCGI Bottle app at some URL, say /myapp , add this to your lighttpd.conf:

fastcgi.server = ( "/myapp" => ( "myapp-fcgi" => ( "socket" => "/run/lighttpd/myapp.sock", "check-local" => "disable", "docroot" => "/", ) ) )

Disabling check-local allows your app to handle URL requests even if a file of the same name does not exist on the local filesystem. For more information on lighttpd and FastCGI, see the official documentation.

Comments

Please enable JavaScript to view the comments powered by Disqus.

Disqus