spbks spbks - 2 months ago 23
Python Question

Initialize a Flask-WhooshAlchemy index when using the app factory pattern

I am developing an app with Flask using the application factory pattern. Initializing the Whoosh index doesn't work, because

current_app
cannot be used without setting up an app context explicitly. How do I do this?

__init__.py


from flask import Flask
from .frontend import frontend

def create_app(configfile=None):
app = Flask(__name__)

from .models import db
db.init_app(app)

app.register_blueprint(frontend)

return app


models.py


from flask_sqlalchemy import SQLAlchemy
import flask_whooshalchemy as wa
from flask import current_app

db = SQLAlchemy()

class Institution(db.Model):
__searchable__ = ['name', 'description']
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(40))
description = db.Column(db.Text)

# this does not work
wa.whoosh_index(current_app, Institution)

Answer

You can't use current_app outside an application context. An application context exists during a request, or when explicitly created with app.app_context().

Import your models during create_app and index them with Whoosh there. Remember, the factory is where you're performing all setup for the application.

def create_app():
    app = Flask('myapp')
    ...
    from myapp.models import Institution
    wa.whoosh_index(app, Institution)
    ...
    return app

If you want to keep the code local to the blueprint, you can use the blueprint's record_once function to perform the index when the blueprint is registered on the app.

@bp.record_once
def record_once(state):
    wa.whoosh_index(state.app, Institution)

This will be called at most once when registering the blueprint with an app. state contains the app, so you don't need the current_app.