How to build a web app using Bottle with Jinja2 in Google App Engine
Posted on Thu 27 Oct 2011 under Web Development

BottleBottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is similar to Flask, but it is even more lightweight and minimal. In fact, the whole framework is contained in a single 44kb file (as of version 0.9.6). If you don't need many of the built-in functions in Flask or any bigger Python web framework, I personally recommend to use Bottle. Now, I am using it to build a simple static website in Google App Engine. Bottle is pluggable to other modules if there's a need to add other goodies. In this post, I'm going to show how to get started with Bottle in Google App Engine. More than the simplest "Hello world!" page, I'd like to show how you can organize your project files so that it becomes manageable as it grows bigger.

The pictures below show the file structure of my sample Bottle project. I am more familiar with Jinja2 template engine so I used it instead of the one that comes with Bottle. Within the project directory (you can give it any name), the top level directories should be app, media, and packages along with the files named app.yaml, index.yaml and main.py. Take note that index.yaml is an auto-generated file. If you don't create it, GAE will create it for you when you run your app.

Top level contents:               Expansion of the child directories:

                  

The app.yaml file contains some configurations for GAE:

application: <your-app-name>
version: 1
runtime: python
api_version: 1

handlers:
  
- url: /media
  static_dir: media

- url: .*
  script: main.py

In your main.py file, the path to the packages directory is added to PYTHONPATH to enable direct import of the modules in that directory. That is where the bottle.py module and Jinja2 package are found.

#!/usr/bin/env python

import sys, os
package_dir = "packages"
package_dir_path = os.path.join(os.path.dirname(__file__), package_dir)
sys.path.insert(0, package_dir_path)

import bottle
from app import views

bottle.debug(True) # Only for debugging purposes, set to False in production
bottle.run(server='gae')

And now, in the app directory, create an empty __init__.py file. In Python, the presence of that file makes the directory a package that you can import and modules within that package can also be imported. That's important for the line "from app import views" in main.py (shown above) to work. The content of the views.py file is as follows:

from bottle import TEMPLATE_PATH, route, jinja2_template as template
from models import *

TEMPLATE_PATH.append("./app/templates")

@route('/')
@route('/hello/:name')
def hello(name='Stranger'):
	return template('home.html', name=name)

We just did here a couple of imports needed for defining the routing or view functions. Then, we added the /app/templates path to the list of paths where Bottle searches for template files. Then we wrote the view functions, but here I just showed one for demonstration. The view function defined in this example can be accessed in two ways (hence the two @route decorators there). 

What's more worth noting here is the return value of the view function. It returns a call to the template function given the file name of the template as argument. In addition you pass as keyword arguments all the variables needed to build the output. In this case, we have the variable "name" which is assigned to "Stranger" unless another name is used in the url /hello/:name (":name" here is the placeholder for any name).

Remember we are using Jinja2 as templating engine. You have to familiarize yourself on its syntax. In this simple example, the "home.html" template looks like this:

{% extends "base.html" %}

{% block content %}

	Hello {{ name }}! How are you?
	
{% endblock %}

"home.html" extends a base template named "base.html". This is the main template that contains the overall layout. This is how it should look like:

<html>
	<head> 
		
		<script type="text/javascript" src="/media/js/jquery-1.6.2.min.js"></script>
		<link type="text/css" rel="stylesheet" href="/media/css/main_template.css"/>

		<title> Sample Bottle App </title>
	</head>

	<body>
	
		{% block content %} {% endblock %}	
	
	</body>

</html>

In the head section of this template, we have links to the jQuery library (which you have to download from their site) and the CSS file for styling. You can drop the jQuery line if you think you won't use it. The body portion contains the Jinja2 tag for a block which I named here as content (you can use any other name). You can make as many blocks as you want then just have other template files extend the base template by filling in some contents on selected blocks.

Now, you're ready to test run your Bottle web app. If you are using the Google App Engine SDK, you just have to create a new application, give it a name, point it to a specific application directory, then just copy all your project files and paste it into the directory that GAE SDK has created. Press the run button, then the browse button, and you will see your app in action. That rundown of steps was rather quick because I assume that you are already familiar with GAE. If not, head over to their site where you can find extensive documentations on how to use it.

You may download the sample app here.


blog comments powered by Disqus