Set up Flask with webassets
A fresh python web app with all the fixins: Sass and Coffeescript
Flask isn’t new, but it’s really great, and it’s definitely my first choice when starting a new Python app. Today I want to give you a quick tour of the tools I use to set up a new Flask app.
I’ll do things nice and step-by-step so you can follow along easily. All the code is on github, too.
Getting started
You will need these package managers to install some of these tools. We don’t discriminate here.
- NPM (Try these install instructions)
- Gem
Now, we want to make a virtualenv (You’ll need virtualenv). Make a new directory to put your project in, then:
$ virtualenv .env
$ .env/bin/activate
Flask Skeleton
We’ll just make a quick app.py
to keep us company. First, install flask:
$ pip install flask
Open up app.py
and put this in it:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run(debug=True)
Preprocessing
I’ve gotten picky about my tools over the years, so here’s what I’m going to demand:
- Sass for css compiling, and
- Coffeescript instead of js
To accomplish that, we’ll use Flask-Assets, which is a thin wrapper around webassets.
So first, let’s install those. This is what we needed npm and gem for. Install sass and coffeescript globally. (We’ll also install Bower for later).
$ sudo gem install sass
$ sudo npm install -g bower coffee-script
From there, we can install some things we’ll probably need. But first, let’s think about the what our project structure will look like. In this case, it’ll be pretty much a standard Flask loadout with the addition of bower. But, we’ll also put our sass and coffeescript files outside the static directory; no need to serve those. So go ahead and make these folders in your project root:
static/
templates/
coffee/
sass/
Now, go into coffee
and sass
and create all.coffee
and all.sass
respectively.
We already installed bower to help us manage our client-side packages. Let’s also go ahead and install jquery:
$ bower init
... fill out the questionnaire ...
$ bower install -S jquery
The -S
in the latter command will cause the these dependencies to be
saved to your bower.json file. You’ll also find that a bower_components
folder has magically appeared, containing jquery.
Finally, let’s install Flask-Assets:
$ pip install flask-assets
Next, we’ll need to define our resource bindles. Open up app.py
and we can
configure webassets:
import os
from flask import Flask, render_template
from flask.ext import assets
app = Flask(__name__)
env = assets.Environment(app)
# Tell flask-assets where to look for our coffeescript and sass files.
env.load_path = [
os.path.join(os.path.dirname(__file__), 'sass'),
os.path.join(os.path.dirname(__file__), 'coffee'),
os.path.join(os.path.dirname(__file__), 'bower_components'),
]
env.register(
'js_all',
assets.Bundle(
'jquery/dist/jquery.min.js',
assets.Bundle(
'all.coffee',
filters=['coffeescript']
),
output='js_all.js'
)
)
env.register(
'css_all',
assets.Bundle(
'all.sass',
filters='sass',
output='css_all.css'
)
)
@app.route("/")
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
Above, we tell webassets about all of our script files, and all of our stylesheets.
Each Bundle
can have a filter applied; we use this fact to apply coffeescript
and
sass
to our files. In the js bundle, we nest the coffeescript files in a bundle
within the main one, so as to only apply the coffeescript filter to the coffeescript files.
If all worked according to plan, when you run your application…
$ python app.py
… you will find that your static folder has js_all.js
and css_all.css
in it.
Now, all that’s left to do is to get your assets into a template. As per Flask-Assets’ instructions, just put the following in a template:
<!doctype html>
<html>
<head>
<title>Hello Flask</title>
{% assets "css_all" %}
<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}"></script>
{% endassets %}
<head>
<body>
<h1>Hello Flask</h1>
{% assets "js_all" %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
</body>
</html>
And that’s it! Anything you put in sass/all.sass or coffee/all.coffee will be updated when you load the page.
If you’d like to grab a copy of this code to use as a starting point for your next project, you can find it on github. Enjoy!