I am playing around with some Flask applications and try to get into Flask-Security. At this point I want to include the roles_required decorator and I am can not get away from this error:
AttributeError: 'Flask' object has no attribute 'before_first_request'. Did you mean: '_got_first_request'?
So far anything else works fine including the @login_required decorator.
run.py
from app import create_app, db
from config import Config
from app.models import User
app = create_app(Config)
if __name__ == '__main__':
app.run(debug=True)
models.py
import secrets
from datetime import datetime
from flask import current_app, request
from flask_security import UserMixin, RoleMixin
from itsdangerous import URLSafeTimedSerializer
from app import db
# Define association table for many-to-many relationship
roles_users = db.Table('roles_users', db.metadata,
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
class User(UserMixin, db.Model):
__tablename__ = 'WEB_Users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
is_active = db.Column(db.Boolean, default=True)
roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic'))
init.py
from flask import Flask, session
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
# Flask-Login-Manager
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
# Flask-App-Factory
db = SQLAlchemy()
migrate = Migrate()
def create_app(config_class):
app = Flask(__name__)
app.config.from_object(config_class)
# Initialize extensions
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
# User loader for Flask-Login
from app.models import User, Role
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# Extend session validity
@app.before_request
def extend_session():
session.permanent = True
# Register blueprints
from app.auth.routes import auth_bp
from app.dashboard.routes import dashboard_bp
app.register_blueprint(auth_bp)
app.register_blueprint(dashboard_bp)
# Setup Flask-Security
from flask_security import Security, SQLAlchemyUserDatastore
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
return app
routes.py
from flask import Blueprint, render_template
from flask_login import login_required
from flask_security import current_user, roles_accepted, roles_required
test = Blueprint('test', __name__)
@test.route('/admin')
@login_required
@roles_required('Admin')
def admin():
print(current_user.roles)
return "Admin"
Could someone help me out with this error?
Please consider using: https://pypi.org/project/Flask-Security-Too/#description
This is a supported fork of the original Flask-Security (with many additional features).
Note that when using Flask-Security - you will need some additional DB fields and you should not have your own UserLoader - let Flask-security handle that.