0

I am attempting to create a Flask middleware in order to make py2neo transactions atomic. First I got a working outside of application context error, and I tried to apply this solution, as seen in the following code:

from flask import g
from py2neo import Graph

def get_db():
    return Graph(password="secret")

class TransactionMiddleware(object):
    def __init__(self, app):
        self.app = app
        with app.app_context():  # Error raises here.
            g.graph = get_db()
            g.transaction = g.graph.begin()

    def __call__(self, environ, start_response):
        try:
            app_status = self.app(environ, start_response)
            # some code
            return app_status
        except BaseException:
            g.transaction.rollback()
            raise
        else:
            g.transaction.commit()

But I got this error: AttributeError: 'function' object has no attribute 'app_context'.

I don't know if the solution I'm trying is not suitable for my case, or what is the problem.

HuLu ViCa
  • 5,077
  • 10
  • 43
  • 93

1 Answers1

0

You are in a WSGI middleware, so what gets passed in as an app is actually a method called Flask.wsgi_app the results of which you a later supposed to return from your __call__ handler.

Perhaps you can simply import your actual flask app and use app_context on that, as in:

from app import app # or whatever module it's in

# and then
class TransactionMiddleware(object):
    ...
    def __call__(self, environ, start_response):   
        with app.app_context():
            ...

I would also consider just instantiating your Graph somehere on a module level. Perhaps next to your flask app instantiation and not attaching it to g. This way you can use it without application context:

# app.py
flask = Flask(__main__)
db = Graph(password="secret")

You can use it by directly importing:

# middleware.py
from app import db
dmitrybelyakov
  • 3,709
  • 2
  • 22
  • 26