from flask import Flask, Blueprint from . import commands, login, target_exchange, target, registration from .exceptions import ApiException from .extensions import db, migrate, jwt, apispec from .settings import ProdConfig, Config def create_app(config: Config = ProdConfig) -> Flask: """An application factory, as explained here: http://flask.pocoo.org/docs/patterns/appfactories/. :param config: The configuration object to use. """ app = Flask(__name__.split('.')[0]) app.url_map.strict_slashes = False app.config.from_object(config) register_extensions(app) register_blueprints(app) register_apispecs(app) register_errorhandlers(app) register_shellcontext(app) register_commands(app) return app def register_extensions(app: Flask): """Register Flask extensions.""" db.init_app(app) migrate.init_app(app, db) jwt.init_app(app) apispec.init_app(app) def register_blueprints(app: Flask): """Register Flask blueprints.""" api_blueprint = Blueprint('api', __name__, url_prefix='/api') api_blueprint.register_blueprint(login.views.blueprint, url_prefix='/login') api_blueprint.register_blueprint(target_exchange.views.blueprint, url_prefix='/target-exchange') api_blueprint.register_blueprint(target.views.blueprint, url_prefix='/target') api_blueprint.register_blueprint(registration.views.blueprint, url_prefix='/registration') app.register_blueprint(api_blueprint) def register_apispecs(app: Flask): """Register routes for apispec Extended from FlaskApiSpec::register_existing_resources that one doesn't handle the static routes or blueprints in blueprints well """ for name, rule in app.view_functions.items(): if name == 'static': continue try: blueprint_name, _ = name.rsplit('.', 1) except ValueError: blueprint_name = None try: apispec.register(rule, blueprint=blueprint_name) except TypeError: pass def register_errorhandlers(app: Flask): def errorHandler(error: ApiException): return error.to_response() app.errorhandler(ApiException)(errorHandler) pass def register_shellcontext(app: Flask): """Register shell context objects.""" def shell_context(): """Shell context objects.""" return { 'db': db, 'TargetExchange': target_exchange.models.TargetExchange, 'Target': target.models.Target, 'Registration': registration.models.Registration, } app.shell_context_processor(shell_context) def register_commands(app: Flask): """Register Click commands.""" app.cli.add_command(commands.clean) app.cli.add_command(commands.urls) app.cli.add_command(commands.seed) app.cli.add_command(commands.setup_rabmq)