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.
Warning
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()
login_manager.init_app(app)
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):
pass
@login_manager.user_loader
def user_loader(username):
if username not in users:
return
user = User()
user.id = username
return user
@login_manager.request_loader
def request_loader(request):
username = request.form.get('username')
password = request.form.get('password', '')
if username not in users:
return
user = User()
user.id = username
user.is_authenticated = compare_digest(password, users[username]['password'])
return user
@login_manager.unauthorized_handler
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>
</form>
'''
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
flask_login.login_user(user)
return redirect(url_for('protected'))
return 'Bad login'
@app.route('/protected')
@flask_login.login_required
async def protected():
return 'Logged in as: ' + flask_login.current_user.id
@app.route('/logout')
async def logout():
flask_login.logout_user()
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.