In my last post I put together a simple template server with Express running on Node for a current project. I only usually use Node for a few build tools and prefer Python on the back-end, so just for the sake of it, here’s a Python alternative.
Using Flask
Flask is a light web framework and very easy to get going with. It’s useful for putting together pages and URL routes with minimal set-up.
Using virtualenv, install with pip:
(env) $ pip install flask
Obligatory “Hello World” app, let’s call it myapp.py:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
Run with the following and visit localhost:5000 in your browser:
(env) $ python myapp.py
Templates use Jinja2, which would have been installed as a dependency when you grabbed Flask.
Syntactically It’s very similar to Django’s templating:
<title>{% block title %}User list{% endblock %}</title>
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
The block tag is used for template inheritance, which is far more useful than including partials everywhere.
For example, a second template can extend the above to reuse the loop logic but update the page title:
{% extends "base.html" %}
{% block title %}Here’s a new title!{% endblock %}
N.B. Since Express matured to 3.x it’s view system concept is going that way too — see migration docs.
Flask provides a render_template method looking for files in a directory named templates, which will sit alongside our application file:
@app.route('/')
def simple():
return render_template('simple.html', message=”Hello World”)
Working with data
Flask’s render_template method sends a view context (dictionary) to the templates, for example the message above. Jinja isn’t logic-less like Mustache, so we can use this context for conditionals, loops and filters.
Refactoring our Javascript code, we can use regular Python load some JSON:
def get_json(path):
file = open(path)
data = json.load(file)
file.close()
return data
@app.route('/')
def simple():
data = get_json(‘data/simple.json’)
return render_template('simple.html', **data)
JSON is far more suited to the other implementation, being entirely Javascript-based.
I can’t say I’ve ever used this approach, for front-end (only) builds I’d just work with a few variables to switch in templates and likely have a shared dictionary for ‘global’ data, e.g. placeholder user info.
On larger projects with back-end work I’d go for Django and a full relational database, though here we’re using static data files.
As for static media files, CSS et al, Flask serves from a static folder which sits alongside our app file and templates directory — this doesn’t have to be specified in the application logic, unlike Express.
Of course, Flask can be used for fully featured applications, three examples:
- flaskr — a microblog
- minitwit — a twitter clone
- the Flask website — static pages and mailing list archives
The Flask Snippets archive is also a great resource, user-provided pieces of code to bootstrap your application — auth, forms, security, sessions etc.
Source files: simple-flask on Github.