Hello everyone I have this issue I am not able to correct:
KeyError: 'A secret key is required to use CSRF.'
I am now using Flask with Blueprint.
I am not using CSRF at all but I think the LoginForm is.
I structured my project with Blueprint.
Before that, everything was find.
Here is my init.py file:
from flask import Flask
from flask_login import LoginManager
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask.config import Config
from flask_wtf.csrf import CSRFProtect
db = SQLAlchemy()
migrate = Migrate(db)
bcrypt = Bcrypt()
csrf = CSRFProtect()
login_manager = LoginManager()
login_manager.login_view = "login"
login_manager.login_message_category = "info"
from Flask import models
from Flask.models import User
admin = Admin(name='Admin')
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
admin.init_app(app)
db.init_app(app)
csrf.init_app(app)
login_manager.init_app(app)
migrate.init_app(app)
bcrypt.init_app(app)
db.init_app(app)
from Flask.users.routes import users
app.register_blueprint(users)
return app
This is my config.py file:
import os
class Config:
SECRET_KEY = "ef2006629e09b70e55a6fb95c4e3a538"
SQLALCHEMY_DATABASE_URI = "sqlite:///site.db"
# WTF_CSRF_SECRET_KEY= "bjk567nvhbvj63vg363vghvghv3768vgfbkijvr784"
# CSRF_ENABLED = True
Thank you for your help !
You should create a SECRET_KEY=<Your secret key here> property in your configuration. It must be a difficult string.
I found the problem
I was not calling properly my config.py file
In my init.py file I change the line:
from flask.config import Config
with the line:
from Flask.config import Config
Flask is the name of my file, which is different from flask.
I should have found another name
Related
My folder structure is the following:
- app.py
app
- __init__.py
- database.py
in app.py I have:
from app import create_app
app = create_app()
my init.py looks something like:
from flask import Flask
from app.database import db_session, init_db
db = SQLAlchemy()
def create_app():
myapp = Flask(__name__, static_folder='static', static_url_path='/static', template_folder="templates")
myapp.config.from_object('config.Config')
db.init_app(myapp)
migrate.init_app(myapp, db)
# loading blueprints
from app.core_bp import core_bp
myapp.register_blueprint(core_bp, url_prefix='/', template_folder="templates")
return myapp
and database.py looks like this
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///rapporteur.db')
db_session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine))
That sqlite path is currently hardcoded to raporteur.db but it should be loaded from config, because I don't want it hardcoded, but unfortunately the flask app is not yet loaded. So how would I do this?
You can use flask-sqlalchemy and set the SQLALCHEMY_DATABASE_URI in the config file.
class Config:
SQLALCHEMY_DATABASE_URI = 'sqlite:///rapporteur.db'
then in your init.py
from youApp import Config
def create_app(config_class=Config)
app = Flask(__name__)
app.config.from_object(config_class)
db = SQLAlchemy()
db.init_app(app)
return app
I have the following structure:
app_dir/
| myapi/
| __init__.py
| myapi_app.py
where myapi_app.py is
from myapi import create_app, db
app = create_app()
and myapi/__init__.py is
import logging
import os
from logging.handlers import RotatingFileHandler
from flask import Flask, request, current_app
from flask_sqlalchemy import SQLAlchemy
from myapi.config import Config
db = SQLAlchemy()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
...
return app
When I set FLASK_APP=myapi_app.py and run flask run from the app_dir directory, the flask service starts. However, when I make a request, I get the following error: flask.cli.NoAppException: Could not import "myapi_app". Where am I going wrong?
Your problem is that you are setting $FLASK_APP to the file in which the app variable is stored, you should instead set it to the python object path, e.g.
FLASK_APP=myapi_app:app
However, this is not necessary, as you could also just do:
FLASK_APP=myapi
as Flask will look for a create_app function in the package on its own.
How to add MySQL config to Flask app and create cursor and use in other classes?
I have 2 files:
app.py:
from flask import Flask
from flask_restful import Api
from Query import Query
from flask_mysqldb impoty MySQL
app= Flask(__name__)
api = Api(app)
api.add_resouce(Query,'/')
app.config['MYSQL_HOST'] = 'host'
#(same for user, password, db)
mysql = MySQL(app)
Query.py:
I am trying to import mysql FROM app.py so I can execute SQL on my DB.
from flask_restfull import Resource
from app import mysql
class Query(Resource):
def get(self):
pass
Error is caused by circular import. How to fix it?
"cannot import name 'Query'
Initialize mysql in another file, and reference it from both query.py and app.py. Inject it into the app using MySQL.init_app method
https://flask-mysqldb.readthedocs.io/en/latest/#flask_mysqldb.MySQL
# database.py
from flask_mysqldb import MySQL
mysql = MySQL()
# query.py
from database import mysql # <--!!!
from flask_restfull import Resource
class Query(Resource):
def get(self):
pass
# app.py
from flask import Flask
from flask_restful import Api
from database import mysql # <--!!!
from query import Query
app = Flask(__name__)
api = Api(app)
api.add_resouce(Query,'/')
app.config['MYSQL_HOST'] = 'host'
mysql.init_app(app) # <--!!!
I've a question related to Flask-migrate.
I'm creating a set of web services with Flask. I've split each web service in his own package in a python application.
The application structure look like this:
MyApp
WS1
models.py
WS2
models.py
CommonPackage
models.py
How can I import all the modules and init the db? I've tried to import them all manually but is not working.
I know that it works if I import the "app" from WS1 or Ws2 separately, but I would like to do this in a single operation, is this possible?
Here you can find the code for Flask-migrate:
#!virtualenv/bin/python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from config import SQLALCHEMY_DATABASE_URI
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
from WS1.models import Class1, Class2, Class3 <--- This is not importing
from WS2.models import Class4, Class5, Class6 <--- This is not importing
if __name__=='__main__':
manager.run()
This is the modules where I initialize SQLAlchemy session:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from config import SQLALCHEMY_DATABASE_URI
engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode = True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
All the models import this module and inherit from Base.
Thanks a lot,
Enrico
When you are defining a custom declarative base you're not really using Flask-SQLAlchemy anymore—and Flask-Migrate reads the models from Flask-SQLAlchemy's internal declarative base. (That is why you have to initialize Migrate with both app and db).
Flask has an answer to the import cycle problem: Most Flask extensions have an .init_app() method to defer initializing the extension where necessary.
In the module where you currently create Base by hand, just do db = SQLAlchemy() and then in your models import db and use db.Models as your declarative base instead of Base. In your app.py, do the following:
from dbpackagename import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db.init_app(app)
for example:
from flask import Flask
from flask.ext.admin import Admin, BaseView, expose
class MyView(BaseView):
#expose('/')
def index(self):
return self.render('index.html')
app = Flask(__name__)
admin = Admin(app)
admin.add_view(MyView(name='Hello'))
app.run()
but, if I need a new file, called 'views.py', how can I add a view into views.py to admin?
Do I need to use a blueprint?
For my project I actually made a child class of Blueprint that supports flask admin:
from flask import Blueprint
from flask_admin.contrib.sqla import ModelView
from flask_admin import Admin
class AdminBlueprint(Blueprint):
views=None
def __init__(self,*args, **kargs):
self.views = []
return super(AdminBlueprint, self).__init__('admin2', __name__,url_prefix='/admin2',static_folder='static', static_url_path='/static/admin')
def add_view(self, view):
self.views.append(view)
def register(self,app, options, first_registration=False):
admin = Admin(app, name='microblog', template_mode='adminlte')
for v in self.views:
admin.add_view(v)
return super(AdminBlueprint, self).register(app, options, first_registration)
For details you may like to read my blog here: http://blog.sadafnoor.me/blog/how-to-add-flask-admin-to-a-blueprint/
I am very late for this question, but anyway... My guess is that you want to use the Application Factory pattern and use the Flask-Admin. There is a nice discussion about the underlying problems. I used a very ugly solution, instantiating the Flask-Admin in the init.py file:
from flask_admin.contrib.sqla import ModelView
class UserModelView(ModelView):
create_modal = True
edit_modal = True
can_export = True
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
# import models here because otherwise it will throw errors
from models import User, Sector, Article
admin.init_app(app)
admin.add_view(UserModelView(User, db.session))
# attach blueprints
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
return app
You don't need a blueprint for that. In views.py add an import for the admin object you defined in your main project:
from projectmodule import admin
from flask.ext.admin import BaseView, expose
class MyView(BaseView):
#expose('/')
def index(self):
return self.render('index.html')
admin.add_view(MyView(name='Hello'))
and in your main projectmodule file use:
from flask import Flask
from flask.ext.admin import Admin
app = Flask(__name__)
admin = Admin(app)
# import the views
import views
app.run()
e.g. you add import views after the line that sets admin = Admin(app).
I have an flask app with one blueprint (and login/logout to admin).
This is the best solution I found to implement flask admin with some custom features.
My structure as follows:
my_app
main
__init__.py
routes.py
static
templates
__init__.py
config.py
models.py
run.py
Customized admin index view from models.py
from flask_admin import AdminIndexView
class MyAdminIndexView(AdminIndexView):
def is_accessible(self):
return current_user.is_authenticated
def inaccessible_callback(self, name, **kwargs):
return redirect(url_for('main.home'))
Main init.py as follows:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.menu import MenuLink
from my_app.config import Config
# create extensions
db = SQLAlchemy()
admin = Admin()
def create_app(config_class=Config): # default configutation
app = Flask(__name__)
app.config.from_object(Config)
#initialize extensions
db.init_app(app)
...
# customized admin views
from my_app.models import MyAdminIndexView
admin.init_app(app,index_view=MyAdminIndexView())
admin.add_link(MenuLink(name='Home', url='/'))
admin.add_link(MenuLink(name='Logout', url='/logout'))
#blueprint
from my_app.main.routes import main
app.register_blueprint(main)
return app
I think this is the most elegant solution I came up so far.
In order to keep clean the __init__.py root file:
# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from app.config import Config
from flask_admin import Admin
db = SQLAlchemy()
admin = Admin(template_mode="bootstrap3")
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
admin.init_app(app)
from app.admin import bp
app.register_blueprint(bp, url_prefix='/admin')
return app
Then in the __init__.py of the Blueprint admin app
# app/admin/__init__.py
from flask import Blueprint
from app import admin, db
from app.models import User
from flask_admin.contrib.sqla import ModelView
bp = Blueprint('admin_app', __name__)
admin.name = 'Admin panel'
admin.add_view(ModelView(User, db.session))
# all the rest stuff