Accessing app object from outside app context in Flask application Accessing app object from outside app context in Flask application flask flask

Accessing app object from outside app context in Flask application


Setting up your app

Initializing your app in the __init__ file of your project is very straightforward, but also very limited when the size of your project becomes bigger (and since you are using blueprints for your routes, I guess that the size of your project is big enough already).

The recommanded way of initializing your app in this case is to use an App factory, which is basically a function that creates and returns the app instance.

Here's a quick example of working arboresence (probably not the best one you will find, but that should do):

# myapp/application/setup.pyfrom flask import Flaskfrom .application.extensions import dbdef create_app():    app = Flask(__name__)    app.config.from_object("myapp.config.Config")    # Initialize extensions    db.init_app(app)    with app.app_context():        db.create_all()        # Register Blueprints        from myapp.player import player        app.register_blueprint(player, url_prefix="/player/")        return app
# myapp/application/extensions.pyfrom flask_sqlalchemy import SQLAlchemy# define global extensions in a separate file so that they can be imported from# anywhere else in the code without creating circular imports# the proper initialization is made within the `create_app` function db = SQLAlchemy()
# myapp/application/app.pyfrom .setup import create_appapp = create_app()
# myapp/__init__.pyfrom .application.app import app
# run.pyfrom myapp import appif __name__ == "__main__":    app.run()

That's it for the hierarchy of your project. At this point, you have a myapp/application/app.py that initialized the app variable, and that you can import from anywhere you want without worrying about the import loops.

Checking headers before calling the view function

With the arboresence I suggested, and considering you update your imports accordingly, your decorator should now be working as expected.But what if I tell you Flask offers a way to do what you want, without implementing a decorator? This is where the before_request kicks in.This is a special function you can write that will be called within the app-context before every single request on your application.

from myapp.application.app import app@app.before_requestdef require_apikey():    if request.headers.get("api-key") != API_KEY:        abort(401, "Invalid API key")

Now the problem here is that this function will be called for every single endpoint you have defined, and maybe that's not what you want. But do not worry, you can also define a before_request function to attach to a specific blueprint.

# myapp/my_blueprint.pyfrom myapp.tools import require_apikeymy_blueprint = Blueprint(...)my_blueprint.before_request = require_apikey