import os import logging from datetime import datetime import asyncio from quart import Quart, url_for, jsonify, render_template, session from quart_session import Session from quart_keycloak import Keycloak, KeycloakAuthToken, KeycloakLogoutRequest from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware import settings app: Quart = None peewee = None cache = None keycloak = None async def _setup_database(app: Quart): import peewee import yellow.models models = peewee.Model.__subclasses__() for m in models: m.create_table() async def _setup_openid(app: Quart): global keycloak keycloak = Keycloak(app, **settings.OPENID_CFG) from yellow.auth import handle_user_login async def _setup_cache(app: Quart): global cache app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_URI'] = settings.REDIS_URI Session(app) async def _setup_error_handlers(app: Quart): @app.errorhandler(500) async def page_error(e): return await render_template('error.html', code=500, msg="Error occurred"), 500 @app.errorhandler(403) async def page_forbidden(e): return await render_template('error.html', code=403, msg="Forbidden"), 403 @app.errorhandler(404) async def page_not_found(e): return await render_template('error.html', code=404, msg="Page not found"), 404 def create_app(): global app app = Quart(__name__) if settings.X_FORWARDED: app.asgi_app = ProxyHeadersMiddleware(app.asgi_app, trusted_hosts=["127.0.0.1", "10.1.0.1"]) app.logger.setLevel(logging.INFO) app.secret_key = settings.APP_SECRET @app.context_processor def template_variables(): from yellow.models import User current_user = session.get('user') if current_user: current_user = User(**current_user) now = datetime.now() return dict(user=current_user, url_login=keycloak.endpoint_name_login, year=now.year) @app.before_serving async def startup(): await _setup_cache(app) await _setup_openid(app) await _setup_database(app) await _setup_error_handlers(app) from yellow.routes import bp_routes from yellow.api import bp_api app.register_blueprint(bp_routes) app.register_blueprint(bp_api) return app