Evan Hahn Evan Hahn - 5 months ago 337
Python Question

Add a prefix to all Flask routes

I have a prefix that I want to add to every route. Right now I add a constant to the route at every definition. Is there a way to do this automatically?

PREFIX = "/abc/123"

@app.route(PREFIX + "/")
def index_page():
return "This is a website about burritos"

@app.route(PREFIX + "/about")
def about_page():
return "This is a website about burritos"

Answer

Assuming that you are going to run this application inside of a WSGI container (mod_wsgi, uwsgi, gunicorn, etc) and you'll be mounting this application inside of it at that prefix, all you need to do is set your APPLICATION_ROOT config value to your prefix:

app.config["APPLICATION_ROOT"] = "/abc/123"

@app.route("/")
def index():
    return "The URL for this page is {}".format(url_for("index"))

# Will return "The URL for this page is /abc/123/"

This simply limit Flask's session cookie to that URL prefix. Everything else will be automatically handled for you by Flask and Werkzeug's excellent WSGI handling capabilities.

If you are not sure what the first paragraph means, take a look at this example application with Flask mounted inside of it:

from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware

app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/abc/123'

@app.route('/')
def index():
    return 'The URL for this page is {}'.format(url_for('index'))

def simple(env, resp):
    resp(b'200 OK', [(b'Content-Type', b'text/plain')])
    return [b'Hello WSGI World']

app.wsgi_app = DispatcherMiddleware(simple, {'/abc/123': app.wsgi_app})

if __name__ == '__main__':
    app.run('localhost', 5000)

If, on the other hand, you will be running this at the root of its WSGI container and simply proxying requests that match that prefix to it then you will want to use a Blueprint, as Miguel points out in his answer.