Tutorial: Using a Flask Extension

This tutorial will guide you through using a Flask extension with Quart. The code for this tutorial is present in the examples/flask_ext directory. The example itself is a very simple webpage that allows a user to login, check a protected route and logout.

Running the example

To run the example, in examples/flask_ext the following should start the server, (see Installation first),

$ export QUART_APP=flask_ext:app
$ quart run

this example is then available at http://localhost:5000/.

1: Installation

It is always best to run python projects within a pipenv, which should be created and activated as follows,

$ cd flask_ext
$ pipenv install quart flask-login

for this we will only need Quart and Flask-Login. Now pipenv can be activated,

$ pipenv shell

3: Using Flask-Login with Quart

Flask-Login is a very popular Flask extension that manages user authentication. To use it with Quart it is important to first activate the flask patching module in Quart, by the following,

import quart.flask_patch

as this allows the extensions to find modules and objects in the flask namespace.


This import must be the first line in your code, i.e. it must be in the main or init module at the top. This line comes with a performance cost.

The Flask-Login extension can now be used, as so,

import quart.flask_patch

import flask_login
from quart import Quart

app = Quart(__name__)
app.secret_key = 'secret'  # Create an actual secret key for production
login_manager = flask_login.LoginManager()

4: Flask-Login setup

Flask-Login requires the following code be present to manage the users, notably to load a User given a request, to load a user given their username and to return a message for unauthorized access,

from secrets import compare_digest

from quart import request

class User(flask_login.UserMixin):

def user_loader(username):
    if username not in users:

    user = User()
    user.id = username
    return user

def request_loader(request):
    username = request.form.get('username')
    password = request.form.get('password', '')
    if username not in users:

    user = User()
    user.id = username
    user.is_authenticated = compare_digest(password, users[username]['password'])
    return user

def unauthorized_handler():
    return 'Unauthorized'

5: Routes

All that is left is to provide login, logout and a protected route to test that the app works. A user can then try to access the protected route when not authorised and then after login. These routes are,

from quart import redirect, url_for

@app.route('/', methods=['GET', 'POST'])
async def login():
    if request.method == 'GET':
        return '''
               <form method='POST'>
                <input type='text' name='username' id='username' placeholder='username'></input>
                <input type='password' name='password' id='password' placeholder='password'></input>
                <input type='submit' name='submit'></input>

    username = (await request.form)['username']
    password = (await request.form)['password']
    if username in users and compare_digest(password, users[username]['password']):
        user = User()
        user.id = username
        return redirect(url_for('protected'))

    return 'Bad login'

async def protected():
    return 'Logged in as: ' + flask_login.current_user.id

async def logout():
    return 'Logged out'

6: Conclusion

The example files contain this entire tutorial and a little more, so they are now worth a read. Hopefully you can now go ahead and create your own apps that use Flask extensions.