Source code for helpers
# -*- coding: utf-8 -*-
"""
Implements useful helpers.
There is the application factory and, maybe,
something else (in the future) to avoid routine.
:copyright: \(c) 2012 by Roman Semirook.
:license: BSD, see LICENSE for more details.
"""
import os
from flask import Flask
from werkzeug.utils import import_string
[docs]class NoContextProcessorException(Exception):
pass
[docs]class NoBlueprintException(Exception):
pass
[docs]class NoExtensionException(Exception):
pass
[docs]class AppFactory(object):
"""
Flask application factory.
>>> app = AppFactory(TestingConfig).get_app(__name__)
"""
[docs] def __init__(self, config, envvar='PROJECT_SETTINGS', bind_db_object=True):
"""
Defines default application settings
:param config: an object to load initial configuration from
:param envvar: The name of an environment variable to update configuration from
:param bind_db_object:
"""
self.app_config = config
self.app_envvar = os.environ.get(envvar, False)
self.bind_db_object = bind_db_object
[docs] def get_app(self, app_module_name, **kwargs):
"""
Actually instanciates a Flask application with active settings,
and taking care of registering extensions and blueprints
:param app_module_name: the name of the application package, see :py:class:`~flask.Flask`
:param kwargs: keyword arguments passed to the Flask constructor
:return: A new WSGI application object
"""
self.app = Flask(app_module_name, **kwargs)
self.app.config.from_object(self.app_config)
self.app.config.from_envvar(self.app_envvar, silent=True)
self._bind_extensions()
self._register_blueprints()
self._register_context_processors()
return self.app
def _get_imported_stuff_by_path(self, path):
module_name, object_name = path.rsplit('.', 1)
module = import_string(module_name)
return module, object_name
def _bind_extensions(self):
for ext_path in self.app.config.get('EXTENSIONS', []):
module, e_name = self._get_imported_stuff_by_path(ext_path)
if not hasattr(module, e_name):
raise NoExtensionException('No {e_name} extension found'.format(e_name=e_name))
ext = getattr(module, e_name)
if getattr(ext, 'init_app', False):
ext.init_app(self.app)
else:
ext(self.app)
def _register_context_processors(self):
for processor_path in self.app.config.get('CONTEXT_PROCESSORS', []):
module, p_name = self._get_imported_stuff_by_path(processor_path)
if hasattr(module, p_name):
self.app.context_processor(getattr(module, p_name))
else:
raise NoContextProcessorException('No {cp_name} context processor found'.format(cp_name=p_name))
def _register_blueprints(self):
for blueprint_path in self.app.config.get('BLUEPRINTS', []):
module, b_name = self._get_imported_stuff_by_path(blueprint_path)
if hasattr(module, b_name):
self.app.register_blueprint(getattr(module, b_name))
else:
raise NoBlueprintException('No {bp_name} blueprint found'.format(bp_name=b_name))