Add a prefix to all Flask routes

StackOverflow

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 rating: 60

You should note that the APPLICATION_ROOT is NOT for this purpose.

All you have to do is to write a middleware to make the following changes:

  1. modify PATH_INFO to handle the prefixed url.
  2. modify SCRIPT_NAME to generate the prefixed url.

Like this:

class PrefixMiddleware(object):

    def __init__(self, app, prefix=""):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):

        if environ["PATH_INFO"].startswith(self.prefix):
            environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix):]
            environ["SCRIPT_NAME"] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response("404", [("Content-Type", "text/plain")])
            return ["This url does not belong to the app.".encode()]

Wrap your app with the middleware, like this:

from flask import Flask, url_for

app = Flask(__name__)
app.debug = True
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix="/foo")


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


if __name__ == "__main__":
    app.run("0.0.0.0", 9010)

Visit http://localhost:9010/foo/bar,

You will get the right result: The URL for this page is /foo/bar

And don"t forget to set the cookie domain if you need to.

This solution is given by Larivact"s gist. The APPLICATION_ROOT is not for this job, although it looks like to be. It"s really confusing.





Tutorials