Flask Web Development

Developing Web Applications with Python

Take full creative control of your web applications with Flask, the Python-based microframework. With this hands-on book, you’ll learn Flask from the ground up by developing a complete social blogging application step-by-step.

If you have some previous Python experience, this book shows you how to take advantage of the creative freedom Flask gives you.

Errata

The following corrections apply to the first and second releases of the first edition of the book. If you have something else to report please contact the author at flaskbookfeedback@gmail.com.

Several chapters
The recommended syntax to import a Flask extension has changed since the book was published. Instead of using from flask.ext.extension import Something it
is now recommended that from flask_extension import Something is used. The Flasky code repository on GitHub has been updated to reflect this.

Chapter 3, Section "Custom Error Pages"
In this section, two custom error page routes are defined, for the 404 and 500 status codes respectively. Later in the section, only the template for the 404 error is shown. The text does not mention that a similar template should be created for the 500 error code. (Reported by Martin Betz)

Chapter 3, Example 3-12
The text around this code example does not clearly specify where in the template file this snippet must be inserted. The location of this snippet does not really matter, because this represents a template block defined by the parent template. (Reported by Martin Betz)

Chapter 3
At the end of the chapter, the language selection feature of Flask-Moment is presented, but it isn't clearly explained where in the template the the language selection primitive needs to be specified. The location should be right after the moment.js library is imported. (Reported by Martin Betz)

Chapter 8, Section "User Authentication with Flask-Login"
Unfortunately version 0.3.0 of Flask-Login introduced changes that break applications that were coded against the 0.2.x versions. More specifically, the User.is_authenticated, User.is_active and User.is_anonymous methods were converted to properties. To port the code to the new release of Flask-Login it is necessary to remove the () when these are accessed. The Flasky repository has been updated to work with the current release. (Reported by several readers)

Chapter 8, Example 8-10
This example code uses the texts "Sign In" and "Sign Out", but the screenshots in this chapter and the code repository use "Log In" and "Log Out". (Reported by Farhad Fouladi)

Chapter 11, Example 11-14
The pathname printed in the heading of this example is incorrect. The correct pathname is app/templates/index.html. (Reported by Trevor Christiansen)

Chapter 11, Example 11-21
The redirect in this code example uses the expression url_for('post', id=post.id). The first argument to the url_for function should instead be '.post', the dot indicates the route should be located in the current blueprint.(Reported by Henry Thiel)

Chapter 12, Example 12-8
The route decorator in this code example should be main.route. (Reported by Libin Feng)

Chapter 13, Example 13-4
The calculation of the page number of the comment uses the / division operator, which has different behavior in Python 2 and Python 3. In this situation integer division is the desired operator, so using // provides the correct output in both versions of Python. (Reported by Kevin Labtani and Serhii Ivashchenko)

Chapter 14, Example 14-4
The pathname printed in the heading of this example is incorrect.The correct pathname is app/api_1_0/errors.py. (Reported by Trevor Christiansen)

Chapter 14, Example 14-9
The generate_auth_token method returns a byte string, without decoding it to a string. The correct return expression for this function is s.dumps({'id': self.id}).decode('ascii'). (Reported by Samuel Woodward)

Chapter 14, Example 14-17
The auth.login_required decorator included in the two routes presented in this code example are not needed, since authentication is taken care of globally for the blueprint. (Reported by Trevor Christiansen)

Chapter 14, Table 14-13
The 6th row in the table has a syntax error in the first column. The correct route is /posts/<int:id>/comments. (Reported by Trevor Christiansen and Samuel Woodwward)

Chapter 15, Example 15-5
The reference to the get_auth_header function is incorrect. The correct function is get_api_headers. (Reported by Samuel Woodward)

Chapter 17, Section "Provisioning a Database"
The command to create a Heroku Postgres database has changed since the book went to print. The updated command is heroku addons:create heroku-postgresql:hobby-dev(Reported by Norbert Stüken)

The following corrections apply only to the first release of the first edition of the book, and were corrected in the second release.

Chapter 3, Example 3-3
The URL of the first route is incorrectly shown as /index, while the correct URL is /. (Reported by Farhad Fouladi)

Chapter 4, Section "HTML Rendering of Forms"
The punctuation in the first sentence is incorrect. The correct sentence should read "Form fields are callables that, when invoked from a template, render themselves to HTML.". (Reported by Ken Hommel)

Chapter 4, Section "HTML Rendering of Forms"
The first two code examples in this section show how to render a form in a template, but are incomplete as they do not show how to implement CSRF protection. The corrected examples are shown below:

The {{ form.hidden_tag() }} line adds a hidden field to the form where Flask-WTF stores the CSRF token. Note that CSRF support is included in Flask-Bootstrap's `wtf.quick_form()` macro, so this is only needed when rendering forms manually. (Reported by Richard Milne)

Chapter 4, Example 4-3
The text that follows the example incorrectly indicates that the format of a Jinja2 conditional is {% if variable %}...{% else %}...{% endif %}, but really should have used the term condition instead of variable. (Reported by Marco Agner)

Chapter 4, Example 4-6
In this example the line of code that reads form.name.data = '' should not be in this function, as it has no effect. (Reported by Steven Marcatante)

Chapter 5, Example 5-4
The pathname printed in the heading of this example is incorrect. The correct pathname is hello.py. (Reported by Napoleon)

Chapter 7, Example 7-5
A dot is missing in the import statement that imports the blueprint. The correct import statement is from .main import main as main_blueprint. (Reported by Erik de Wildt)

Chapter 8, Example 8-9
The example does not import the Length validator. The import line that imports the validators is: from wtforms.validators import Required, Length, Email. (Reported by Ken Hommel and Dan Carpenter)

Chapter 8, Example 8-20
The pathname printed in the heading of this example is incorrect. The correct pathname is app/templates/auth/email/confirm.txt. (Reported by John Baham, Jr.)

Chapter 8, Example 8-22
The before_request() handler was coded to deny any requests outside of the auth blueprint, but this effectively prevents static files from being served. Normally this isn't a problem because the static files were already cached in the client web browser, but a correct handler is shown below:

Chapter 10, Example 10-8
The code example contains a typo. The line that reads db.session.add(user) should be db.session.add(current_user). (Reported by Lukasz Gabrych)

Chapter 11, Example 11-15, and Chapter 12, Examples 12-3, 12-7, 12-10, 12-11
The pathname printed in the heading of these examples is incorrect. The correct pathname is app/models.py. (Reported by John Baham, Jr.)

Chapter 14, section "Creating an API Blueprint"
The filenames of some of the files in the api_1_0 folder are in singular, while they should be plural to match the source code on GitHub. These are users.py, posts.py and comments.py. (Reported by John Baham, Jr.)

Chapter 15, Example 15-5
The "write a post" portion of the test includes an incorrect body string that does not have correct Markdown styling. The correct sentence should be data = json.dumps ({ 'body' : 'body of the *blog* post' })). (Reported by Dmitry Zhuravlev-Nevsky)

An Introduction to Flask

First Steps in Web Development with Python

Get started with Flask, the popular web framework that’s small, lightweight, and powerful. This video tutorial uses use short and simple examples to help beginning Python developers explore the features of Flask and some of its extensions.

You’ll learn topics central to most web applications such as routing, templates, web forms, and user sessions, along with a brief introduction to databases and user logins. By the end of the class unit testing and application deployment are also explored.

The approximate duration of this course is 4 hours and 17 minutes. The first two chapters are available to watch for free at oreilly.com.

Example Code

This course features a variety of example projects that demonstrate specific features of the Flask framework or its related extensions. You are welcome to browse through the source code.

Table Of Contents

Introduction

Welcome and Set Up

Hello, Flask!

A Simple "Hello World" Application

Templates

Introduction to Templates

Using Jinja2 Templates

Using Flask-Bootstrap

Custom Error Pages

Page Links

Web Forms

Working with Web Forms

Form Management and Validation with Flask-WTF

Rendering Forms with Flask-Bootstrap

File Uploads

Flask In Depth

Understanding Contexts

Request Dispatching

Request Hooks

Responses

Databases

Using Flask-SQLAlchemy

User Logins

Password Security

Using Flask-Login

Scalable Application Structure

Scalable Application Structure

Testing

Writing Unit Tests & Code Coverage

End-to-end testing with the Flask Test Client

Deployment

Running in Production Mode

Deploying to Heroku

Deploying to a Linux Server

Building Web APIs with Flask

Techniques for Developing Modern Web Services with Python

If you want to build web services and APIs, this video course shows you how to do it with Flask, the popular web framework that’s small, lightweight, and powerful. Using detailed examples, Miguel Grinberg shows you how to create APIs for database backed services as well as Internet enabled devices.

The approximate duration of this course is 3 hours and 32 minutes. The first two chapters are available to watch for free at oreilly.com.

Example Code

This course is structured around two example API projects:

orders: a service that exposes an orders database to clients.

camera: a service that allows clients to take and view pictures and timelapse sequences. This project is designed to run on a Raspberry Pi with a camera module, but can also run in emulation mode in a regular computer without specialized camera hardware.