from flask import Flask, g, request, flash, render_template from flask_jwt_extended import current_user import os import time from .auth import blueprint as users_blueprint, jwt from .routes import blueprint as main_blueprint from .util.log import set_up_logging from .api import blueprint as api_blueprint from .applicant import blueprint as apply_blueprint from .cors import cors from app.model import db from app import config from flask_mongoengine import MongoEngineSessionInterface def config_from_environ(app, prefix=None): if not prefix: prefix = app.config.get('APP_NAME') for name, value in os.environ.items(): if name.startswith(prefix): if isinstance(value, str): value = value.strip() if value: app.config[name[len(prefix) + 1:]] = value def create_app(app_name=None, config_override={}, config_objs=[], permanent_session_ttl=None, add_ping=True, ping_url='/api/ping'): if not config_objs: config_objs = [config] if not app_name: app_name = 'QUARTER_WEB' app_root_path = os.path.abspath(os.path.dirname(__file__)) app = Flask(app_name, template_folder=os.path.join(app_root_path, 'templates'), static_folder=os.path.join(app_root_path, 'static')) for obj in config_objs: app.config.from_object(obj) # configure any environment variables config_from_environ(app) for key, value in config_override.items(): app.config[key] = value # init all the app components db.init_app(app) jwt.init_app(app) cors.init_app(app) app.session_interface = MongoEngineSessionInterface(db) app.secret_key = config.SECRET_KEY app.permanent_session_lifetime = permanent_session_ttl if permanent_session_ttl else app.config.get('PERMANENT_SESSION_TTL') app.register_blueprint(api_blueprint, url_prefix='/api') for blueprint in [main_blueprint, users_blueprint, apply_blueprint]: app.register_blueprint(blueprint) set_up_logging(app, app_name) @app.errorhandler(401) def unauthorized(e): flash('You are not authorized to access this page, please log in') return render_template('auth/unauthorized.html') @app.before_request def before_request(): g.start = time.time() @app.after_request def after_request(response): request_time = time.time() - g.start app.logger.info(f'HTTP request completed (method={request.method}, path={request.path}, status_code={response.status_code}, request_time={request_time}s, user={current_user.user_id if current_user else "None"})') return response if add_ping: @app.route(ping_url) def ping(): return {'ready': True}, 200 return app