Building Flask Apps for Speed and Scale

Get Started, Faster; Build Bigger, Faster

Learn You A Flask For Great Good!

Our team recently built the MVP of KeyringNow, currently in Beta. It was not only a lot of fun to build, we were once again pleased with how quickly we were able to build and deploy with Flask!

If you’re not familiar with Flask, it’s my pleasure to introduce you! There are few web frameworks in any language more popular than Flask.

Of course, there’s Django, the heavyweight in the python community – and for good reason. Django comes “batteries included”, but it’s more like “18-wheel fuel tanker” included. It brings a plugin system, a configuration management system, an ORM, and more. It’s HEAVY.

Flask, on the other hand, is a micro-framework. It basically just handles request and response parsing, routing, and templating. It lets you start small, like really small, as in a single file small. It grows as your project and team grows.

Being a micro-framework, Flask isn’t particularly opinionated about how to do any one thing. That’s good and bad. It means there’s a lot of competing info on how best to accomplish a task in Flask. This blog post is no different.

This post won’t be a good introduction to Flask – you’ll want to look at the official tutorials for that – what I am going to do is give you a glimpse of my secret recipe for building applications quickly, and making sure it can grow with you. You’ll see how a self-deigned “power-user” uses Flask.

Cookiecutter

Cookiecutter is the python community’s project templating tool. It lets you run

cookiecutter $GIT_URL

then it asks for some parameters (like projec title), then it generates a full project structure for you from the $GIT_URL template.

This is the secret herbs and spices in my secret recipe:

A Flask Cookiecutter Template

Ok, maybe it’s not much of a secret. But it’s my officially recommended method of starting Flask apps, for what that’s worth.

It has everything you need to build a full-featured app:

  • SQLAlchemy (ORM) built in with Alembic SQL migrations
  • Flask-Login for user accounts and sessions
  • Bootstrap and WTForms for front-end templates and HTML form handling (and webpack integration already set up)
  • Heroku (Procfile) 1-click deployment

and that’s just the highlights!

Setting Yourself Up For Success

The key to starting small and growing large with Flask is to utilize blueprints.

Blueprints are units of modularity, or reuse, that you can define in a Flask application. Here’s an example:

  1. user blueprint
  • serving routes under /user for things like profile, settings, and billing
  1. chat blueprint
  • serving the /chat page, which might be a chatroom.

Of course, the user profile and chatroom may require a user to be logged in, and you need to serve pages that aren’t “authenticated”, so you have a:

  1. public blueprint
  • served at / (the root url), which might have pages like /register and /login!

This is the structure I usually start with for my Flask apps:

my_app (root)
├── my_app
│   ├── __init__.py
│   ├── app.py
│   ├── commands.py
│   ├── database.py
│   ├── ext (extensions like email, external apis, etc)
│   ├── public (public blueprint)
│   │   ├── templates
│   │   │	  └── home.html
│   │   ├── views.py
│   │   └── __init__.py
│   ├── user (user blueprint)
│   │   ├── templates
│   │   │	  └── home.html
│   │   ├── views.py
│   │   └── __init__.py
│   ├── chat (chatroom blueprint)
│   │   ├── templates
│   │   │	  └── home.html
│   │   ├── views.py
│   │   └── __init__.py
│   ├── static
│   │   ├── build
│   │   └── js
│   ├── templates (global/shared templates)
│   └── webpack
├── migrations
├── tests
├── Procfile
...more build scripts, etc

The important part here is the public and my_blueprint directories. These are the two initial blueprints. These are used in the app.py application factory like so:

import public, user, chat

...

def register_blueprints(app):
	app.register_blueprint(public.views.blueprint)
	app.register_blueprint(user.views.blueprint, url_prefix="/user")
	app.register_blueprint(chat.views.blueprint, url_prefix="/chat")
	
...

And you’ve got beautifully separated application logic, stitched together as one application by Flask!

Using Flask-Login and Flask-SQLAlchemy (both included in the cookiecutter), it makes authenticating and authorizing views as simple as possible.

In this way, you can add new features that are entirely separate, and update or remove individual features without affecting the others. Having an admin blueprint is very common (Flask-Admin is super useful for that – it’s not included in cookiecutter, but it’s a breeze to add).

A Few Improvements

  1. Pipenv

I recently wrote about why pipenv is Havercene’s recommended tool for python dependency management. I should note that the Flask cookiecutter does not use pipenv out of the box, but it’s a snap to convert the requirements.txt:

pipenv install -r requirements.txt

  1. Flask-Admin

Like I mentioned above, Flask-Admin is invaluable for adding “admin” pages to your application, i.e. pages where you can see the registered users, or any other entity you have in your SQLAlchemy connection. It lets you create, update, and delete entities, all from your web browser – no more writing raw SQL!

If you’re interested in learning how we use Flask-Admin, I hope to write another article on exactly that! Let me know if that’s something you want to see! As always, if you have any questions about the information in this post, or if you want some advice on how to use Flask (or any other python framework) my email address is at the bottom of this page.

If you're working on projects like this, I'd love to hear from you! If you have any questions or thoughts about this article, please reach out! Or, if you have a topic you'd like me to write about next, let me know!
[email protected]