"""The main app entrypoint""" import logging from flask import Flask, render_template from flask_alembic import Alembic from flask_bcrypt import Bcrypt from flask_mail import Mail from flask_sqlalchemy import SQLAlchemy from flask_debugtoolbar import DebugToolbarExtension alembic = Alembic() bcrypt = Bcrypt() mail = Mail() db = SQLAlchemy() toolbar = DebugToolbarExtension() def create_app(**config): """create a flask instance and initialize plugins""" app = Flask(__name__) app.config.from_pyfile('config.py') app.config.from_pyfile('../instance/config.py', silent=True) app.config.from_mapping(config) if app.config['ENV'] == 'testing': # pragma: no branch app.config['TESTING'] = True # Flask-Mail needs this app.config.update(SQLALCHEMY_DATABASE_URI=app.config['TESTING_DB']) alembic.init_app(app) bcrypt.init_app(app) mail.init_app(app) db.init_app(app) toolbar.init_app(app) # register index page app.add_url_rule('/', 'index', lambda: render_template('index.html')) # register blueprints # pylint: disable=cyclic-import from .blueprints import BLUEPRINTS for blueprint in BLUEPRINTS: app.register_blueprint(blueprint) # register lifecycle methods from app.lifecycle import authenticate app.before_request(authenticate) # setup logging of 500 errors # pylint: disable=unused-argument def internal_error_handler(exc): # pragma: no cover logger = logging.getLogger('app.errors') logger.exception('Internal Server Error') return '500 error', 500 app.register_error_handler(500, internal_error_handler) return app