# -*- coding: utf-8 -*- # Copyright (c) 2017 Tomek Wójcik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # """ q3stats.web_app.application =========================== This module contains the Web application core. """ import flask from werkzeug.exceptions import HTTPException from q3stats import __version__ as app_version import q3stats.database from q3stats.lib.config import get_config_path class Q3StatsApplication(flask.Flask): """Customized ``flask.Flask`` subclass.""" def init_db(self): """Creates the SQLAlchemy engine and session for this instance.""" if q3stats.database.db_engine is None: q3stats.database.db_engine = q3stats.database.create_engine( self.config ) if q3stats.database.db_session is None: q3stats.database.db_session = q3stats.database.create_session( q3stats.database.db_engine, self.config ) @self.teardown_request def shutdown_session(exception=None): q3stats.database.db_session.remove() @property def db_session(self): """The SQLAlchemy session for the current context.""" return q3stats.database.db_session def create_app(config_path=None): """The application factory. Creates an instance of :py:class:`Q3StatsApplication` and sets its config from file located at *config_path*.""" app = Q3StatsApplication(__name__) if config_path is None: config_path = get_config_path() app.config.from_pyfile(config_path) app.init_db() @app.context_processor def app_context_processor(): return { 'version': app_version } @app.errorhandler(400) @app.errorhandler(404) @app.errorhandler(500) def app_handle_error(error): error_code = 500 if isinstance(error, HTTPException): error_code = error.code return flask.render_template( 'error.html', error_code=error_code ), error_code from .blueprints.frontend import frontend_blueprint app.register_blueprint(frontend_blueprint) from .blueprints.api_v1 import api_v1_blueprint app.register_blueprint(api_v1_blueprint) return app