Цель состоит в том, чтобы написать простое расширение Flask. В качестве руководства я использую справку по разработке расширений Flask . Я также изучил исходные коды flask-sqlalchemy и flask-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