flask-security
flask-security copied to clipboard
security.context_processor raises RecursionError
I try to use flask_security with flask_admin, but at start up there's a problem with the context_processor:
File "/home/lionel/dev/knmx/knmx/launcher.py", line 6, in <module>
from knmx.app import create_app
File "/home/lionel/dev/knmx/knmx/app.py", line 92, in <module>
@webui_security.context_processor
File "/home/lionel/dev/knmx/venv/lib/python3.5/site-packages/flask_security/core.py", line 531, in __getattr__
return getattr(self._state, name, None)
File "/home/lionel/dev/knmx/venv/lib/python3.5/site-packages/flask_security/core.py", line 531, in __getattr__
return getattr(self._state, name, None)
...
RecursionError: maximum recursion depth exceeded
My setup:
- app.py
from flask import Flask
from knmx import config
from knmx import security
from knmx.db import models
from knmx.views import api, admin, webui, schemas
def create_app(extra_config=None):
app = Flask(__name__.split('.')[0])
app.config.from_object(config.DefaultConfig)
register_extensions(app=app)
def register_extensions(app):
models.db.init_app(app=app)
security.webui_security.init_app(app=app, datastore=security.user_datastore)
security.jwt.init_app(app=app)
admin.admin.init_app(app=app)
- security.py
from flask_security import Security, SQLAlchemyUserDatastore
from flask_jwt_extended import JWTManager
from knmx.db import models
webui_security = Security()
jwt = JWTManager()
user_datastore = SQLAlchemyUserDatastore(models.db, models.User, models.Role)
- admin.py
from flask import redirect, url_for, request, abort
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_admin import helpers as admin_helpers
from flask_security import current_user
from knmx.db import models
from knmx.security import webui_security
admin = Admin()
@webui_security.context_processor
def security_context_processor():
return dict(
admin_base_template=admin.base_template,
admin_view=admin.index_view,
h=admin_helpers,
get_url=url_for
)
Hi, @LionelR I also face the issue just like you.
I find out that in version 3.0.0's flask_security.Security init_app
function is a little bit different from __init__
.
It won't assign self._state
when using init_app
way, but it'll return state object for you.
So, I guess, that's why the getattr
would never find context_processor
attribute in self._state
. 😢
For now, I found there are two ways to fix this issue,
- Using
init_app
return value
secur = security.webui_security.init_app(app=app, datastore=security.user_datastore)
@secur.context_processor
def security_context_processor():
...
- Get state object from app.extension after you
init_app
security = app.extension['security']
@security.context_processor
def security_context_processor():
...
Or you can just use the develop branch code.
I saw someone add self._state = state = _get_state(app, datastore, **kwargs)
to fix this problem.
(CODE LINK)
Hope it will help you.
Any update on this? I still have the same issue (following @LionelR's approach) ...
- I found this as a fix
security_state = security.init_app(app,user_datastore)
security._state = security_state
Please consider moving to: https://github.com/Flask-Middleware/flask-security
which is my updated and maintained fork. The fix mentioned above is there.
i am use template: {% set admin_base_template = security.admin_base_template %} {% set admin_view = security.admin_view %} {% set get_url = security.get_url %} {% set h = security.h %} {% extends 'admin/master.html' %}
use in: security.init_app(app, user_datastore, admin_base_template=admin.base_template, admin_view=admin.index_view, h=admin_helpers, get_url=url_for)
Work! Not use @...context_processor