If you're using
slack_bolt, you've probably encountered this exception when accessing
db within your Slack requests handlers:
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
db you define with
flask_sqlalchemy needs access to
flask.current_app. This is available anywhere you import
flask, but as it turns out
current_app isn't a
Flask instance as you might expect.
current_app is an instance of
LocalProxy from the
werkzeug package and it returns the Flask instance for the current context. It gets a bit in-depth here, but Werkzeug implements something called context locals for accessing global variables in a thread-safe way.
With this in mind, we get that exception because
slack_bolt handles Slack requests in a new thread and
flask.current_app isn't bound to a
Flask instance in that thread. The solution is simple - bind
flask.current_app to your Flask app for the handler thread. Flask's documentation describes how to do this here.
In my application I used a middleware since middleware is still executed in the main thread and has access to the Flask app:
def bind_flask_app(context, next): context['flask_app'] = current_app._get_current_object() next() @slack_app.command("/some_slash_command", middleware=[bind_flask_app]) context['flask_app'].app_context().push()