An Intro to Flask

In my last post, I presented a high level overview of what a web application is. In this post, we'll take a look at how how you can use Flask (a python based app framework) to build applications by breaking down a series of examples, culminating with the app from this official flask tutorial. I won't dive deeply into the code for that example here, as the tutorial above already does that. Instead, I will build up to it with two of my own examples, and provide a visual representation of it.

NOTE: I highly recommend the tutorial if you want a deeper dive into Flask.

What is Flask?

Flask is a Python based micro-framework for building web applications. It's "micro" simply because it's minimalist, meaning it has fewer built-in features than other frameworks.

How is an app constructed using Flask?

Consider a basic app - one that has a single view which simply shows the phrase, "Hello, World!" Using Flask, we can build this app with a single file. This file would be stored in a directory (app) with a single file (app.py):

app
|- app.py

The contents of app.py:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello, World!'

The code above defines an application using the Flask object (a class that represents an application). This appication serves a single view, which you can request via the route /. When you request this view, the code attached to this route is executed, and Flask responds with a simple line of text - "Hello, World!"

To run this app on a Linux or Mac machine, you would run the commands:

export FLASK_APP=app
export FLASK_ENV=development
flask run

Here's what would happen:

  1. Flask spins up a server on your local computer. This server listens for requests for the domain http://127.0.0.1:5000.
  2. The view for the route / would be returned when you visit the base domain above.

What would a more complicated example look like?

The app above is fairly straightforward. Let's try to visualize what a more complicated example would look like by expanding our app to include two more views: one that returns Foo. and one that returns Bar. We'll add these new views via a Blueprint - an object that enables you to group views. It also allows you to better organize your code by enabling you to break your views out into multiple files.

Here's a visual representation of our app:

Note our app is a Flask object with 3 views, each defined under a route. Two of our views are grouped via a Blueprint.

We'll need to organize our files a little differently by changing app.py to __init__.py, and by nesting the app directory in a new directory flask_example:

flask_example
|- app
    |- __init__.py
    |- foobar.py

Our code for running the app will not change. However, we need to execute the commands from the flask_example directory. Why? We do this for namespace reasons - in order for our app file (now __init__.py) to import our blueprint (defined in foobar.py), we need to treat the app directory like a Python module.

Our code for __init__.py is now:

from flask import Flask
from . import foobar

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello, World!'

app.register_blueprint(foobar.bp)

And our code for foobar.py is:

from flask import Blueprint

bp = Blueprint('foobar', __name__, url_prefix='/foobar')


@bp.route('/foo')
def foo():
    return 'Foo.'


@bp.route('/bar')
def bar():
    return 'Bar.'

What would a slightly more complicated example look like?

The example above is great, but what if you wanted your views to use HTML instead of simple text phrases? Great news! You easily do so by using templates - Jinja files you can use to construct more complex views.

Let's add a template for each of our views. Please note that I won't get into the specifics of Jinja syntax here, nor will I define the template files. I'll leave that part to you as a creative exercise ;) But if you'd like to learn more, I recommend reading the Jinja docs.

Our app will now look like this:

We'll need to add a new directory for our templates:

flask_example
|- app
    |- __init__.py
    |- foobar.py
    |- templates
        |- index.html
        |- foobar
            |- foo.html
            |- bar.html

And by slightly modifying our code for __init__.py:

from flask import Flask
from . import foobar

app = Flask(__name__)


@app.route('/')
def hello():
    render_template('index.html`)

app.register_blueprint(foobar.bp)

And foobar.py:

from flask import Blueprint

bp = Blueprint('foobar', __name__, url_prefix='/foobar')


@bp.route('/foo')
def foo():
    render_template('foobar/foo.html`)


@bp.route('/bar')
def bar():
    render_template('foobar/bar.html`)

What would an even MORE complicated example look like?

I'll cover one final example: flaskr, a simple blogging app you can build using an official Flask tutorial. You should be ready to tackle it on your own by now, but I want to give you a visual representation of the app before you start.

The app has 5 views, split between 2 blueprints:

  • blog
    • /: The site index. If a user is logged in, shows their posts. If not, shows login options.
    • /create: Allows a logged in user to create and save a new blog post.
    • /update: Allows a logged in user to edit an existing blog post.
  • auth
    • /register: Allows a user to create an account with a username and password.
    • /login: Allows a user to login to an existing account.

Note that this app also has an additional component: a mySQL database with two tables: user (which stores user data) and post (which stores post data).

With that, here's a visual overview:

Closing Remarks

Hope you found this helpful! I know that writing this and creating the visualizations above really helped cement the Flask fundamentals for me. The next posts in this series will cover some additional backend basics, in no particular order: logging, testing and algorithm design.