Расширения Flask, контекст и Neo4j

Цель состоит в том, чтобы написать простое расширение Flask. Я использую справочник по разработке расширений Flask в качестве руководства. Я также изучил исходный код фляги-sqlalchemy и фляги-mongoengine для подсказок.

Моя проблема заключается в использовании соединения Neo4j за пределами представлений. Я сталкиваюсь с проблемами контекста приложения и, похоже, застрял в кругу.

Супер простое приложение Flask с использованием заводского метода.

# project.app

from flask import Flask, register_blueprint
from project.extensions import graph
from project.blueprints.user import user_blueprint


def create_app():
    app = Flask(__name__)
    app.register_blueprint(user_blueprint)
    register_extensions(app)
    return app


def register_extensions(app):
    graph.init_app(app)
    return None

Пример расширения после ссылки на колбу в качестве руководства. Возвращает соединение Neo4j в контексте.

# project.extensions

from flask import current_app, _app_ctx_stack
from py2neo import Graph

class Neo4j(object):
    def __init__(self, app=None):
        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        app.config.setdefault('NEO4J_URI', 'http://localhost:7474/db/data')
        app.teardown_appcontext(self.teardown)

    def connect(self):
        return Graph(current_app.config['NEO4J_URI'])

    def teardown(self, exception):
        ctx = _app_ctx_stack.top
        if hasattr(ctx, 'graph'):
            # py2neo doesn't support closing connections
            pass

    @property
    def connection(self):
        ctx = _app_ctx_stack.top
        if ctx is not None:
            if not hasattr(ctx, 'graph'):
                ctx.graph = self.connect()
            return ctx.graph

graph = Neo4j()

Где у меня начинаются проблемы. Я получаю RuntimeError: Working outside of application context ошибка.

# project.utils.neo4j

from project.extensions import graph
from py2neo.ogm import GraphObject, Property


class GraphMixin(GraphObject):
    def add(self):
        # this works in sqlalchemy through "sessions"
        graph.connection.create(self)
        return self
    def delete(self):
        graph.connection.delete(self)

Простая пользовательская модель, которая наследует GraphMixin,

# project.blueprints.user.models

import uuid
from py2neo.ogm import Property
from project.utils.neo4j import GraphMixin


class User(GraphMixin):

    __primarykey__ = 'id'

    email = Property()
    password = Property()

    def __init__(self, email, password, **kwargs):
        self.id = str(uuid.uuid4().hex)
        self.email = email
        self.password = password  # yes this is encrypted in real life

    def get_id(self):
        return self.id

Я не могу использовать with app.app_context: в моем GraphMixin класс, потому что у меня нет доступа к app не создавая его (я должен создавать app экземпляр каждый раз, когда я получаю доступ к user модель).

Как я могу встроить расширение в контекст приложения для использования внутри и за пределами представлений?

Python==3.6
Flask==0.12
Py2neo==3.1.2

0 ответов

Другие вопросы по тегам