Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python flask do something at each route

Tags:

python

flask

I have a flask app where I have to delete and update user information, like this (simplified):

@app.route('/<user>')
def show_user(user):
    """ Show user information """
    render_template('show_user.html')

@app.route('/delete/<user>')
def delete_user(user):
    """ Delete user from database """
    delete_user_from_db(user)
    return redirect(url_for('show_users', user=user)

@app.route('/update/<user>', method=["POST"])
def update_user(user):
    """ Update user information """
    update(user, stuff_from_POST)
    return redirect(url_for('show_users', user=user)

For each of these methods I need to verify whether the user specified in the URL is really a valid user, so I'd do something like this at the beginning of all those functions:

if user not in mydb:
    do(something)
    abort(404)

This is rather cumbersome, and since I will be having more functions that depend on the user to be valid, I was wondering if it were possible to wrap that block in another function that gets automatically executed when those routes are called.

Thanks in advance.

like image 339
John Bergson Avatar asked Oct 16 '25 15:10

John Bergson


1 Answers

Use the before_request hook function see docs

@app.before_request
def before_request():
    if user not in mydb:
    do(something)
    abort(404)

Edit:

I tried this

from flask import Flask, request
app = Flask(__name__)

db = ['paul', 'steve', 'anna']

@app.before_request
def before_request():
    if request.endpoint in ['show_user', 'delete_user', 'update_user']:
        user = request.path[request.path.rfind('/') + 1:]
        if user not in db:
            return 'user not found', 404

@app.route('/<user>')
def show_user(user):
    """ Show user information """
    return 'hello %s' % user

@app.route('/other')
def show_other():
    """ Demonstrates other routes are not effected by before_request """
    return 'other stuff'

if __name__ == "__main__":
    app.run()

It's not actually as neat as I hoped but it works.

It's a little unfortunate to have to maintain which endpoints do what in the before_request function. If you were doing REST you might be able to merge these endpoints into one and simply use different http methods for each action.

like image 101
Paul Rooney Avatar answered Oct 19 '25 04:10

Paul Rooney