Source code for flask_unchained.hooks.configure_app_hook

import flask

from typing import *

from ..config import BundleConfig
from ..app_factory_hook import AppFactoryHook
from ..bundles import Bundle, AppBundle
from ..constants import DEV, PROD, STAGING, TEST
from ..flask_unchained import FlaskUnchained


BASE_CONFIG_CLASS = 'Config'

ENV_CONFIG_CLASSES = {
    DEV: 'DevConfig',
    PROD: 'ProdConfig',
    STAGING: 'StagingConfig',
    TEST: 'TestConfig',
}


[docs]class ConfigureAppHook(AppFactoryHook): """ Updates ``app.config`` with the settings from each bundle. """ name = 'configure_app' """ The name of this hook. """ bundle_module_name = 'config' """ The default module this hook loads from. Override by setting the ``config_module_name`` attribute on your bundle class. """ require_exactly_one_bundle_module = True run_after = ['register_extensions']
[docs] def run_hook(self, app: FlaskUnchained, bundles: List[Bundle], unchained_config: Optional[Dict[str, Any]] = None, ) -> None: """ For each bundle in ``unchained_config.BUNDLES``, iterate through that bundle's class hierarchy, starting from the base-most bundle. For each bundle in that order, look for a ``config`` module, and if it exists, update ``app.config`` with the options first from a base ``Config`` class, if it exists, and then also if it exists, from an env-specific config class: one of ``DevConfig``, ``ProdConfig``, ``StagingConfig``, or ``TestConfig``. """ BundleConfig._set_current_app(app) self.apply_default_config(app, bundles and bundles[-1] or None) for bundle in bundles: app.config.from_mapping(self.get_bundle_config(bundle, app.env)) _config_overrides = (unchained_config.get('_CONFIG_OVERRIDES') if unchained_config else None) if _config_overrides and isinstance(_config_overrides, dict): app.config.from_mapping(_config_overrides)
def apply_default_config(self, app: FlaskUnchained, app_bundle: Optional[Bundle] = None, ) -> None: from .. import config app.config.from_object(config._ConfigDefaults) if app.env == DEV: app.config.from_object(config._DevConfigDefaults) elif app.env == TEST: app.config.from_object(config._TestConfigDefaults) if isinstance(app_bundle, AppBundle): app_bundle_config = self.get_bundle_config(app_bundle, app.env) app.config.from_mapping(app_bundle_config)
[docs] def get_bundle_config(self, bundle: Bundle, env: Union[DEV, PROD, STAGING, TEST], ) -> flask.Config: """ Get the config settings from a bundle hierarchy. """ if isinstance(bundle, AppBundle): return self._get_bundle_config(bundle, env) config = flask.Config('.') for bundle_ in bundle._iter_class_hierarchy(): config.update(self._get_bundle_config(bundle_, env)) return config
def _get_bundle_config(self, bundle: Union[AppBundle, Bundle], env: Union[DEV, PROD, STAGING, TEST], ) -> flask.Config: """ Get the config settings from a single bundle package. """ config = flask.Config('.') try: bundle_config_module = self.import_bundle_modules(bundle)[0] except IndexError: return config base_config = getattr(bundle_config_module, BASE_CONFIG_CLASS, None) env_config = getattr(bundle_config_module, ENV_CONFIG_CLASSES[env], None) for config_cls in [base_config, env_config]: if config_cls: config.from_object(config_cls) return config