コード例 #1
0
ファイル: wsgi.py プロジェクト: mrvanes/CMservice
def create_app(config: dict = None):
    app = Flask(__name__, static_url_path='', instance_relative_config=True)

    if config:
        app.config.update(config)
    else:
        app.config.from_envvar("CMSERVICE_CONFIG")

    mako = MakoTemplates()
    mako.init_app(app)
    app._mako_lookup = TemplateLookup(
        directories=[
            pkg_resources.resource_filename('cmservice.service', 'templates')
        ],
        input_encoding='utf-8',
        output_encoding='utf-8',
        imports=['from flask_babel import gettext as _'])

    app.cm = init_consent_manager(app)

    babel = Babel(app)
    babel.localeselector(get_locale)
    app.config[
        'BABEL_TRANSLATION_DIRECTORIES'] = pkg_resources.resource_filename(
            'cmservice.service', 'data/i18n/locales')

    from .views import consent_views
    app.register_blueprint(consent_views)

    setup_logging(app.config.get('LOGGING_LEVEL', 'INFO'))

    logger = logging.getLogger(__name__)
    logger.info("Running CMservice version %s",
                pkg_resources.get_distribution("CMservice").version)
    return app
コード例 #2
0
ファイル: i18n.py プロジェクト: freedomofpress/securedrop
def setup_app(config, app):
    global LOCALES
    global babel

    translation_dirs = getattr(config, 'TRANSLATION_DIRS', None)

    if translation_dirs is None:
            translation_dirs = \
                    path.join(path.dirname(path.realpath(__file__)),
                              'translations')

    # `babel.translation_directories` is a nightmare
    # We need to set this manually via an absolute path
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = translation_dirs

    babel = Babel(app)
    if len(list(babel.translation_directories)) != 1:
        raise AssertionError(
            'Expected exactly one translation directory but got {}.'
            .format(babel.translation_directories))

    translation_directories = next(babel.translation_directories)
    for dirname in os.listdir(translation_directories):
        if dirname != 'messages.pot':
            LOCALES.append(dirname)

    LOCALES = _get_supported_locales(
        LOCALES,
        getattr(config, 'SUPPORTED_LOCALES', None),
        getattr(config, 'DEFAULT_LOCALE', None),
        translation_directories)

    babel.localeselector(lambda: get_locale(config))
コード例 #3
0
ファイル: i18n.py プロジェクト: zenmonkeykstop/securedrop
def setup_app(config, app):
    global LOCALES
    global babel

    translation_dirs = getattr(config, 'TRANSLATION_DIRS', None)

    if translation_dirs is None:
        translation_dirs = path.join(path.dirname(path.realpath(__file__)),
                                     'translations')

    # `babel.translation_directories` is a nightmare
    # We need to set this manually via an absolute path
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = translation_dirs

    babel = Babel(app)
    if len(list(babel.translation_directories)) != 1:
        raise AssertionError(
            'Expected exactly one translation directory but got {}.'.format(
                babel.translation_directories))

    translation_directories = next(babel.translation_directories)
    for dirname in os.listdir(translation_directories):
        if dirname != 'messages.pot':
            LOCALES.append(dirname)

    LOCALES = _get_supported_locales(
        LOCALES, getattr(config, 'SUPPORTED_LOCALES', None),
        getattr(config, 'DEFAULT_LOCALE', None), translation_directories)

    babel.localeselector(lambda: get_locale(config))
コード例 #4
0
ファイル: test_filters.py プロジェクト: abilian/abilian-core
def app():
    app = Flask(__name__)
    babel = Babel(app, default_locale="fr", default_timezone=USER_TZ)
    babel.localeselector(en_locale)
    babel.timezoneselector(user_tz)
    with app.app_context():
        yield app
コード例 #5
0
ファイル: app.py プロジェクト: EvaSDK/original
def create_app(config=None):
    app = Flask(__name__.split('.')[0])
    app_config = {  # Defaults
        'GALLERY_ROOT': os.path.abspath(os.path.join(
            os.path.dirname(__file__), '..', 'gallery'
        )),
        'REDIS_URL': 'redis://localhost:6379/0',
    }

    if config is not None:
        app_config.update({key.upper(): value
                           for key, value in config.items()})
        if 'DEBUG' in app_config:
            if app_config['DEBUG'] in ('0', 'n', 'no', 'False', 'false'):
                app_config.update({'DEBUG': False})
            else:
                app_config.update({'DEBUG': True})

    app.config.update(app_config)

    app.add_url_rule('/galleries/<path:path>', view_func=send_pic, methods=['GET'])

    babel = Babel(app)
    babel.localeselector(get_locale)
    app.jinja_env.filters['date'] = format_date
    app.jinja_env.filters['datetime'] = format_datetime

    GalleryView.register(app)
    return app
コード例 #6
0
def app():
    app = Flask(__name__)
    babel = Babel(app, default_locale="fr", default_timezone=USER_TZ)
    babel.localeselector(en_locale)
    babel.timezoneselector(user_tz)
    with app.app_context():
        yield app
コード例 #7
0
ファイル: wsgi.py プロジェクト: its-dirg/ALservice
def create_app(config: dict = {}, mail_client=None):
    app = Flask(__name__, static_folder='static')

    if config:
        app.config.update(config)
    else:
        app.config.from_envvar('ALSERVICE_CONFIG')

    MakoTemplates(app)
    app._mako_lookup = TemplateLookup(directories=[pkg_resources.resource_filename('alservice.service', 'templates')],
                                      input_encoding='utf-8', output_encoding='utf-8',
                                      imports=['from flask_babel import gettext as _'])

    app.al = init_account_linking(app, mail_client)

    babel = Babel(app)
    babel.localeselector(get_locale)
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = pkg_resources.resource_filename('alservice.service',
                                                                                  'data/i18n/locales')

    from .views import account_linking_views
    app.register_blueprint(account_linking_views)

    setup_logging(app.config.get('LOGGING_LEVEL', 'INFO'))

    logger = logging.getLogger(__name__)
    logger.info('Running ALservice version %s', pkg_resources.get_distribution('ALservice').version)

    return app
コード例 #8
0
ファイル: wsgi.py プロジェクト: its-dirg/CMservice
def create_app(config: dict = None):
    app = Flask(__name__, static_url_path='', instance_relative_config=True)

    if config:
        app.config.update(config)
    else:
        app.config.from_envvar("CMSERVICE_CONFIG")

    mako = MakoTemplates()
    mako.init_app(app)
    app._mako_lookup = TemplateLookup(directories=[pkg_resources.resource_filename('cmservice.service', 'templates')],
                                      input_encoding='utf-8', output_encoding='utf-8',
                                      imports=['from flask_babel import gettext as _'])

    app.cm = init_consent_manager(app)

    babel = Babel(app)
    babel.localeselector(get_locale)
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = pkg_resources.resource_filename('cmservice.service',
                                                                                  'data/i18n/locales')

    from .views import consent_views
    app.register_blueprint(consent_views)

    setup_logging(app.config.get('LOGGING_LEVEL', 'INFO'))

    logger = logging.getLogger(__name__)
    logger.info("Running CMservice version %s", pkg_resources.get_distribution("CMservice").version)
    return app
コード例 #9
0
def setup_app(config: SDConfig, app: Flask) -> None:
    global LOCALES
    global babel

    # `babel.translation_directories` is a nightmare
    # We need to set this manually via an absolute path
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = str(
        config.TRANSLATION_DIRS.absolute())

    babel = Babel(app)
    if len(list(babel.translation_directories)) != 1:
        raise AssertionError(
            'Expected exactly one translation directory but got {}.'.format(
                babel.translation_directories))

    translation_directories = next(babel.translation_directories)
    for dirname in os.listdir(translation_directories):
        if dirname != 'messages.pot':
            LOCALES.append(dirname)

    LOCALES = _get_supported_locales(LOCALES, config.SUPPORTED_LOCALES,
                                     config.DEFAULT_LOCALE,
                                     translation_directories)

    babel.localeselector(lambda: get_locale(config))
コード例 #10
0
ファイル: initialization.py プロジェクト: agdsn/sipa
def init_app(app, **kwargs):
    """Initialize the Flask app located in the module sipa.
    This initializes the Flask app by:
    * calling the internal init_app() procedures of each module
    * registering the Blueprints
    * registering the Jinja global variables
    :return: None
    """
    load_config_file(app, config=kwargs.pop('config', None))
    app.wsgi_app = ProxyFix(app.wsgi_app, app.config['NUM_PROXIES'])
    init_logging(app)
    init_env_and_config(app)
    logger.debug('Initializing app')
    login_manager.init_app(app)
    babel = Babel()
    babel.init_app(app)
    babel.localeselector(select_locale)
    app.before_request(save_user_locale_setting)
    app.session_interface = SeparateLocaleCookieSessionInterface()
    cf_pages = CategorizedFlatPages()
    cf_pages.init_app(app)
    backends = build_backends_ext()
    backends.init_app(app)
    QRcode(app)

    app.url_map.converters['int'] = IntegerConverter

    from sipa.blueprints import bp_features, bp_usersuite, \
        bp_pages, bp_documents, bp_news, bp_generic, bp_hooks

    logger.debug('Registering blueprints')
    app.register_blueprint(bp_generic)
    app.register_blueprint(bp_features)
    app.register_blueprint(bp_usersuite)
    app.register_blueprint(bp_pages)
    app.register_blueprint(bp_documents)
    app.register_blueprint(bp_news)
    app.register_blueprint(bp_hooks)

    logger.debug('Registering Jinja globals')
    form_label_width = 3
    form_input_width = 7
    app.jinja_env.globals.update(
        cf_pages=cf_pages,
        get_locale=get_locale,
        get_weekday=get_weekday,
        possible_locales=possible_locales,
        get_attribute_endpoint=get_attribute_endpoint,
        should_display_traffic_data=should_display_traffic_data,
        traffic_chart=provide_render_function(generate_traffic_chart),
        current_datasource=backends.current_datasource,
        form_label_width_class="col-sm-{}".format(form_label_width),
        form_input_width_class="col-sm-{}".format(form_input_width),
        form_input_offset_class="col-sm-offset-{}".format(form_label_width),
        url_self=url_self,
    )
    logger.debug("Jinja globals have been set",
                 extra={'data': {'jinja_globals': app.jinja_env.globals}})

    backends.init_backends()
コード例 #11
0
ファイル: locale.py プロジェクト: City-of-Helsinki/ghgdash
def init_locale(server):
    babel = Babel(default_locale='fi')
    babel.init_app(server)

    server.add_url_rule('/language/<lang>', 'change_language', view_func=change_language)

    # Monkeypatch Plotly to accept lazystrings
    plotly_utils.PlotlyJSONEncoder = JSONEncoder
    babel.localeselector(get_active_locale)
コード例 #12
0
def decorate_helper(app):

    # Add custom template filters
    for key, func in filter_list_mapping.items():
        app.template_filter(key)(func)

    babel = Babel(app)

    def get_locale():
        translations = [
            str(translation) for translation in babel.list_translations()
        ]
        return request.accept_languages.best_match(translations)

    babel.localeselector(get_locale)

    return app
コード例 #13
0
ファイル: kiosk.py プロジェクト: shinycore/kiosk
def create_app():
    app = Flask(__name__)

    app.config["BABEL_TRANSLATION_DIRECTORIES"] = "../translations"

    app.add_url_rule("/", browse.__name__, browse, methods=("GET", ))

    app.add_url_rule("/", add_entry.__name__, add_entry, methods=("POST", ))
    app.add_url_rule("/entry/<int:idx>",
                     delete_entry.__name__,
                     delete_entry,
                     methods=("DELETE", ))

    babel = Babel(app)
    babel.localeselector(lambda: request.accept_languages.best_match(
        ("en", "pl")))

    return app
コード例 #14
0
ファイル: i18n.py プロジェクト: jingru97/securedrop
def configure_babel(config: SDConfig, app: Flask) -> None:
    """
    Set up Flask-Babel according to the SecureDrop configuration.
    """
    # Tell Babel where to find our translations.
    translations_directory = str(config.TRANSLATION_DIRS.absolute())
    app.config["BABEL_TRANSLATION_DIRECTORIES"] = translations_directory

    # Create the app's Babel instance. Passing the app to the
    # constructor causes the instance to attach itself to the app.
    babel = Babel(app)

    # verify that Babel is only using the translations we told it about
    if list(babel.translation_directories) != [translations_directory]:
        raise ValueError(
            "Babel translation directories ({}) do not match SecureDrop configuration ({})"
            .format(babel.translation_directories, [translations_directory]))

    # register the function used to determine the locale of a request
    babel.localeselector(lambda: get_locale(config))
コード例 #15
0
ファイル: __init__.py プロジェクト: vipulgupta2048/aslo-v3
def init_app():
    app = Flask(__name__)
    app.config.from_object('aslo.settings')

    from .i18n import set_lang_redirect, get_app_locale
    set_lang_redirect(app)

    # init Babel
    babel = Babel(app)
    babel.localeselector(get_app_locale)

    # init celery
    from .celery_app import init_celery
    init_celery(app)

    # blueprints
    from .web import web
    app.register_blueprint(web)

    from .api import api
    app.register_blueprint(api, url_prefix='/api')

    # logging
    logger.setLevel(logging.INFO)
    fmt = logging.Formatter('[%(asctime)s] %(levelname).3s %(message)s')
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(fmt)
    logger.addHandler(stream_handler)

    if app.config['DEBUG']:
        logger.setLevel(logging.DEBUG)

    # setup db
    from .service import setup_db
    setup_db(app)

    # custom jinja filters
    from .filters import init_filters
    init_filters(app)

    return app
コード例 #16
0
def setup_app(app, translation_dirs=None):
    global babel

    if translation_dirs is None:
        translation_dirs = \
                path.join(path.dirname(path.realpath(__file__)),
                          'translations')

    # `babel.translation_directories` is a nightmare
    # We need to set this manually via an absolute path
    app.config['BABEL_TRANSLATION_DIRECTORIES'] = translation_dirs

    babel = Babel(app)
    if len(list(babel.translation_directories)) != 1:
        raise AssertionError(
            'Expected exactly one translation directory but got {}.'.format(
                babel.translation_directories))

    for dirname in os.listdir(next(babel.translation_directories)):
        if dirname != 'messages.pot':
            LOCALES.add(dirname)

    babel.localeselector(get_locale)
コード例 #17
0
ファイル: babel.py プロジェクト: Vito2015/tcc3-portal
class TCC3Babel(object):
    DEFAULT_LOCALE = 'zh_Hans_CN'

    def __init__(self, app=None):
        self._locale = TCC3Babel.DEFAULT_LOCALE
        self.babel = Babel()
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        """:type app : Flask"""

        self.babel.init_app(app)
        self.babel.localeselector(TCC3Babel.get_locale)

    def set_locale(self, locale=DEFAULT_LOCALE):
        self._locale = locale
        # TODO

    @classmethod
    def get_locale(cls):
        locale = request.accept_languages.best_match(LANGUAGES.keys())
        print('locale: ', locale)
        return locale
コード例 #18
0
ファイル: test_filters.py プロジェクト: debon/abilian-core
 def create_app(self):
     app = Flask(__name__)
     babel = Babel(app, default_locale='fr', default_timezone=USER_TZ)
     babel.localeselector(en_locale)
     babel.timezoneselector(user_tz)
     return app
コード例 #19
0
ファイル: engine.py プロジェクト: zhoudaqing/appkernel
class AppKernelEngine(object):
    def __init__(self,
                 app_id: str,
                 app: Flask = None,
                 root_url: str = '/',
                 log_level=logging.DEBUG,
                 cfg_dir: str = None,
                 development: bool = False,
                 enable_defaults: bool = True):
        """
        Initialiser of Flask Engine.
        :param app: the Flask App
        :type app: Flask
        :param root_url: the url where the service are exposed to.
        :type root_url: str
        :param log_level: the level of log
        :param cfg_dir: the directory containing the cfg.yml file. If not provided it will be taken from the command line or from current working dir;
        :param development: the system will be initialised in development mode if True. If None, it will try to read the value as command line parameter or default to false;
        :type log_level: logging
        """
        assert app_id is not None, 'The app_id must be provided'
        assert re.match(
            '[A-Za-z0-9-_]', app_id
        ), 'The app_id must be a single word, no space or special characters except - or _ .'
        self.app: Flask = app or Flask(app_id)
        assert self.app is not None, 'The Flask App must be provided as init parameter.'
        try:
            config.service_registry = {}
            self.before_request_functions = []
            self.after_request_functions = []
            self.app_id = app_id
            self.root_url = root_url
            self.__configure_flask_app()
            self.__init_web_layer()
            self.cmd_line_options = get_cmdline_options()
            self.cfg_dir = cfg_dir or self.cmd_line_options.get('cfg_dir')
            self.cfg_engine = CfgEngine(self.cfg_dir, optional=enable_defaults)
            config.cfg_engine = self.cfg_engine
            self.__init_babel()
            self.__init_cross_cutting_concerns()
            self.__init_event_loop()
            self.development = development or self.cmd_line_options.get(
                'development')
            cwd = self.cmd_line_options.get('cwd')
            self.init_logger(log_folder=cwd, level=log_level)
            # -- initialisation
            # this can raise false positives if a bit of code running
            # longer than 1 seconds.
            # the timeout can be increased by adding the parameter:
            # resolution=3, where the value 3 represents 3 seconds.
            eventlet.debug.hub_blocking_detection(True, resolution=3)
            atexit.register(self.shutdown_hook)
            if hasattr(app, 'teardown_appcontext'):
                app.teardown_appcontext(self.teardown)
            elif hasattr(app, 'teardown_request'):
                app.teardown_request(self.teardown)
            # -- database host
            db_host = self.cmd_line_options.get('db') or self.cfg_engine.get(
                'appkernel.mongo.host', 'localhost')
            db_name = self.cfg_engine.get('appkernel.mongo.db', 'app')
            self.mongo_client = MongoClient(host=db_host)
            config.mongo_database = self.mongo_client[db_name]
            config.flask_app: Flask = self.app
            config.app_engine = self
        except (AppInitialisationError, AssertionError) as init_err:
            # print >> sys.stderr,
            self.app.logger.error(init_err.message)
            sys.exit(-1)

    def enable_security(self, authorisation_method=None):
        self.enable_pki()
        if not authorisation_method:
            authorisation_method = authorize_request
        self.add_before_request_function(authorisation_method)
        config.security_enabled = True
        return self

    def enable_pki(self):
        if not hasattr(self.app, 'public_key'):
            self.__init_crypto()

    def add_before_request_function(self, func):
        self.before_request_functions.append(func)

    def add_after_request_function(self, func):
        self.after_request_functions.append(func)

    @staticmethod
    def __init_event_loop():
        # todo: implement event loop
        # config.event_loop = asyncio.get_event_loop()
        pass

        def shutdown_eventloop():
            if 'event_loop' in config.__dict__ and config.event_loop and config.event_loop.is_running(
            ):
                logging.info('shutting down the event loop.')
                config.event_loop.shutdown_asyncgens()
                config.event_loop.stop()

        atexit.register(shutdown_eventloop)

    def __init_cross_cutting_concerns(self):
        def create_function_chain_executor(chain):
            def function_chain_executor():
                for func in chain:
                    return func()

            return function_chain_executor

        # todo: journaling request responses
        # todo: rate limiting
        self.app.before_request(
            create_function_chain_executor(self.before_request_functions))
        # todo: add after request processor
        # self.app.after_request(create_function_chain_executor(self.after_request_functions))

    def __init_crypto(self):
        # https://stackoverflow.com/questions/29650495/how-to-verify-a-jwt-using-python-pyjwt-with-public-key
        with self.app.app_context():
            with open('{}/keys/appkernel.pem'.format(self.cfg_dir),
                      "rb") as key_file:
                private_key = serialization.load_pem_private_key(
                    key_file.read(), password=None, backend=default_backend())
                config.private_key = private_key
            with open('{}/keys/appkernel.pub'.format(self.cfg_dir),
                      'rb') as key_file:
                public_key = serialization.load_pem_public_key(
                    key_file.read(), backend=default_backend())
                config.public_key = public_key

    def __init_babel(self):
        self.babel = Babel(self.app)
        # translations = Translations.load('translations')
        # translations.merge(Translations.load())
        # todo: support for multiple plugins
        supported_languages = []
        for supported_lang in self.cfg_engine.get('appkernel.i18n.languages',
                                                  ['en-US']):
            supported_languages.append(supported_lang)
            if '-' in supported_lang:
                supported_languages.append(supported_lang.split('-')[0])

        def get_current_locale():
            with self.app.app_context():
                best_match = request.accept_languages.best_match(
                    supported_languages, default='en')
                return best_match.replace('-', '_')

        self.babel.localeselector(get_current_locale)
        # catalogs = gettext.find('locale', 'locale', all=True)
        # self.logger.info('Using message catalogs: {}'.format(catalogs))

    @property
    def logger(self):
        return self.app.logger

    def run(self):
        self.app.logger.info('===== Starting {} ====='.format(self.app_id))
        self.app.logger.debug(f'--> registered routes:\n {self.app.url_map}')
        if self.development:
            self.app.logger.info(f'--> initialising in development mode...')
            self.app.run(debug=self.development, threaded=True)
            # todo: make the threading and deployment configurable
            # self.app.run(debug=self.development, processes=8)
        else:
            try:
                from gevent.pywsgi import WSGIServer, LoggingLogAdapter
                port = self.cfg_engine.get('appkernel.server.port', 5000)
                binding_address = self.cfg_engine.get(
                    'appkernel.server.address', '')
                backlog = self.cfg_engine.get('appkernel.server.backlog', 256)
                logging_adapter = LoggingLogAdapter(self.app.logger)
                self.http_server = WSGIServer((binding_address, port),
                                              application=self.app,
                                              backlog=backlog,
                                              log=logging_adapter,
                                              error_log=logging_adapter)
                shutdown_timeout = self.cfg_engine.get(
                    'appkernel.server.shutdown_timeout', 10)
                self.app.logger.info(
                    f'--> starting production mode |host: {binding_address}|port: {port}|backlog: {backlog}'
                )
                print(f'=== starting server ===')
                self.http_server.serve_forever(stop_timeout=shutdown_timeout)
            except ImportError:
                self.app.logger.warning(
                    '--> falling back to the builtin development server (since gevent is missing / issue: pip install gevent'
                )
                self.app.run(debug=self.development, threaded=True)

    def shutdown_hook(self):
        if config and hasattr(config,
                              'mongo_database') and config.mongo_database:
            self.mongo_client.close()
        if hasattr(self, 'app') and self.app and hasattr(
                self.app, 'logger') and self.app.logger:
            self.app.logger.info('======= Shutting Down {} ======='.format(
                self.app_id))
        # no need for the following code snippet while the http_server.serve_forever() is used
        # if hasattr(self, 'http_server'):
        #     self.http_server.stop(10)

    @staticmethod
    def get_cmdline_options():
        # working dir is also available on: self.app.root_path
        argv = sys.argv[1:]
        opts, args = getopt.getopt(
            argv, 'c:dw:', ['config-dir=', 'development', 'working-dir='])
        # -- config directory
        config_dir_provided, config_dir_param = AppKernelEngine.is_option_provided(
            ('-c', '--config-dir'), opts, args)
        cwd = os.path.dirname(os.path.realpath(sys.argv[0]))
        if config_dir_provided:
            cfg_dir = '{}/'.format(str(config_dir_param).rstrip('/'))
            cfg_dir = os.path.expanduser(cfg_dir)
            if not os.path.isdir(cfg_dir) or not os.access(cfg_dir, os.W_OK):
                raise AppInitialisationError(
                    'The config directory [{}] is not found/not writable.'.
                    format(cfg_dir))
        else:
            cfg_dir = None

        # -- working directory
        working_dir_provided, working_dir_param = AppKernelEngine.is_option_provided(
            ('-w', '--working-dir'), opts, args)
        if working_dir_provided:
            cwd = os.path.expanduser('{}/'.format(
                str(config_dir_param).rstrip('/')))
            if not os.path.isdir(cwd) or not os.access(cwd, os.W_OK):
                raise AppInitialisationError(
                    'The working directory[{}] is not found/not writable.'.
                    format(cwd))
        else:
            cwd = '{}/../'.format(cwd.rstrip('/'))
        development, param = AppKernelEngine.is_option_provided(
            ('-d', '--development'), opts, args)
        return {'cfg_dir': cfg_dir, 'development': development, 'cwd': cwd}

    def __configure_flask_app(self):
        if hasattr(self.app, 'teardown_appcontext'):
            self.app.teardown_appcontext(self.teardown)
        else:
            self.app.teardown_request(self.teardown)
        if not hasattr(self.app, 'extensions'):
            self.app.extensions = {}
        self.app.extensions['appkernel'] = self

    def __init_web_layer(self):
        self.app.json_encoder = AppKernelJSONEncoder
        self.app.register_error_handler(Exception, self.generic_error_handler)
        for code in default_exceptions.keys():
            # add a default error handler for everything is unhandled
            self.app.register_error_handler(code, self.generic_error_handler)

            def set_locale_on_request():
                g.locale = str(get_locale())

            self.app.before_request(set_locale_on_request)

    def init_logger(self, log_folder, level=logging.DEBUG):
        assert log_folder is not None, 'The log folder must be provided.'
        if self.development:
            formatter = logging.Formatter("%(levelname)s - %(message)s")
            handler = logging.StreamHandler()
            handler.setLevel(level)
            self._enable_werkzeug_logger(handler)
        else:
            # self.cfg_engine.get_value_for_section()
            # log_format = ' in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s'
            formatter = logging.Formatter(
                "%(asctime)s - %(levelname)s - %(name)s:%(lineno)d - %(message)s"
            )
            max_bytes = self.cfg_engine.get('appkernel.logging.max_size',
                                            10485760)
            backup_count = self.cfg_engine.get(
                'appkernel.logging.backup_count', 3)
            file_name = self.cfg_engine.get(
                'appkernel.logging.file_name'
            ) or f"{self.app_id.replace(' ', '_').lower()}.log"
            handler = RotatingFileHandler('{}/{}'.format(
                log_folder, file_name),
                                          maxBytes=max_bytes,
                                          backupCount=backup_count)
            # handler = TimedRotatingFileHandler('logs/foo.log', when='midnight', interval=1)
            handler.setLevel(level)
        handler.setFormatter(formatter)
        self.app.logger.setLevel(level)
        # self.app.logger.addHandler(handler)
        self.app.logger.handlers = [handler]
        self.app.logger.info('Logger initialised')

    @staticmethod
    def _enable_werkzeug_logger(handler):
        logger = logging.getLogger('werkzeug')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(handler)

    def generic_error_handler(self,
                              ex: Exception = None,
                              upstream_service: str = None):
        """
        Takes a generic exception and returns a json error message which will be returned to the client
        :param ex: the exception which is reported by this method
        :param upstream_service: the servicr name which generated this error
        :return:
        """
        code = (ex.code if isinstance(ex, HTTPException) else 500)
        if ex and code != 404:
            msg = '{}/{}'.format(
                ex.__class__.__name__,
                ex.description if isinstance(ex, HTTPException) else str(ex))
            self.logger.exception('generic error handler: {}/{}'.format(
                ex.__class__.__name__, str(ex)))
        elif ex and code == 404:
            msg = '{} ({} {}): {}'.format(
                ex.__class__.__name__, request.method, request.url,
                ex.description if isinstance(ex, HTTPException) else str(ex))
            self.logger.exception('generic error handler: {}/{}'.format(
                ex.__class__.__name__, str(ex)))
        else:
            msg = 'Generic server error.'
            self.logger.warning('generic error handler: {}/{}'.format(
                ex.__class__.__name__, str(ex)))
        return create_custom_error(code,
                                   msg,
                                   upstream_service=upstream_service)

    def teardown(self, exception):
        """
        context teardown based deallocation
        :param exception:
        :type exception: Exception
        :return:
        """
        if exception is not None:
            self.app.logger.warning(exception.message if hasattr(
                exception, 'message') else str(exception))

    def register(self,
                 service_class_or_instance,
                 url_base=None,
                 methods=['GET'],
                 enable_hateoas=True) -> ResourceController:
        """

        :param service_class_or_instance:
        :param url_base:
        :param methods:
        :param enable_hateoas:
        :return:
        :rtype: Service
        """
        if inspect.isclass(service_class_or_instance):
            assert issubclass(
                service_class_or_instance, (Model)
            ), 'Only subclasses of Model can be registered as class. If you want to register a controller, please use its instance.'

        from appkernel.service import expose_service
        expose_service(service_class_or_instance,
                       self,
                       url_base or self.root_url,
                       methods=methods,
                       enable_hateoas=enable_hateoas)
        return ResourceController(service_class_or_instance)
コード例 #20
0
def init_app(app, **kwargs):
    """Initialize the Flask app located in the module sipa.
    This initializes the Flask app by:
    * calling the internal init_app() procedures of each module
    * registering the Blueprints
    * registering the Jinja global variables
    :return: None
    """
    load_config_file(app, config=kwargs.pop('config', None))
    app.wsgi_app = ProxyFix(app.wsgi_app, app.config['NUM_PROXIES'])
    init_logging(app)
    init_env_and_config(app)
    logger.debug('Initializing app')
    login_manager.init_app(app)
    babel = Babel()
    babel.init_app(app)
    babel.localeselector(select_locale)
    app.before_request(save_user_locale_setting)
    app.session_interface = SeparateLocaleCookieSessionInterface()
    cf_pages = CategorizedFlatPages()
    cf_pages.init_app(app)
    backends = Backends()
    backends.init_app(app)

    app.url_map.converters['int'] = IntegerConverter

    from sipa.blueprints import bp_features, bp_usersuite, \
        bp_pages, bp_documents, bp_news, bp_generic, bp_hooks

    logger.debug('Registering blueprints')
    app.register_blueprint(bp_generic)
    app.register_blueprint(bp_features)
    app.register_blueprint(bp_usersuite)
    app.register_blueprint(bp_pages)
    app.register_blueprint(bp_documents)
    app.register_blueprint(bp_news)
    app.register_blueprint(bp_hooks)

    from sipa.model import query_gauge_data
    logger.debug('Registering Jinja globals')
    form_label_width = 3
    form_input_width = 7
    app.jinja_env.globals.update(
        cf_pages=cf_pages,
        gauge_data=query_gauge_data,
        get_locale=get_locale,
        get_weekday=get_weekday,
        possible_locales=possible_locales,
        get_attribute_endpoint=get_attribute_endpoint,
        traffic_chart=provide_render_function(generate_traffic_chart),
        credit_chart=provide_render_function(generate_credit_chart),
        current_datasource=backends.current_datasource,
        form_label_width_class="col-sm-{}".format(form_label_width),
        form_input_width_class="col-sm-{}".format(form_input_width),
        form_input_offset_class="col-sm-offset-{}".format(form_label_width),
        url_self=url_self,
    )
    logger.debug("Jinja globals have been set",
                 extra={'data': {'jinja_globals': app.jinja_env.globals}})

    backends.init_backends()
コード例 #21
0
def set_locale():
    """
    Set the locale in the session to one of the available languages.
    If a language has been given via the URL, it is set if it is a valid
    language. If no language has been given via the URL and no language
    is present in the session, the default language will be determined
    according to what the user's browser prefers.
    """
    if "lang" in request.args and request.args["lang"] in language_list:
        session["lang"] = request.args["lang"]
    if "lang" not in session:
        session["lang"] = request.accept_languages.best_match(language_list)
    g.languages, g.locales = language_list, locales


babel.localeselector(get_locale)
c3bottles.before_request(set_locale)

# Trim and strip blocks in jinja2 so no unnecessary
# newlines and tabs appear in the output:
c3bottles.jinja_env.trim_blocks = True
c3bottles.jinja_env.lstrip_blocks = True

from view.api import api
from view.main import index, faq, dp_list, dp_map, dp_view
from view.create import create_dp
from view.edit import edit_dp
from view.report import report
from view.visit import visit
from view.user import login, logout
from view.statistics import stats
コード例 #22
0
ファイル: test_filters.py プロジェクト: debon/abilian-core
 def create_app(self):
   app = Flask(__name__)
   babel = Babel(app, default_locale='fr', default_timezone=USER_TZ)
   babel.localeselector(en_locale)
   babel.timezoneselector(user_tz)
   return app
コード例 #23
0
def get_locale() -> str | None:
    """Get locale.

    Returns:
        The locale that should be used for Babel. If not given as an option to
        Fava, guess from browser.
    """
    lang = g.ledger.fava_options.language
    if lang is not None:
        return lang
    return request.accept_languages.best_match(["en"] + LANGUAGES)


BABEL = Babel(app)
BABEL.localeselector(get_locale)


for function in template_filters.FILTERS:
    app.add_template_filter(function)  # type: ignore
app.add_template_filter(serialise)


@app.url_defaults
def _inject_filters(endpoint: str, values: dict[str, str | None]) -> None:
    if "bfile" not in values and app.url_map.is_endpoint_expecting(
        endpoint, "bfile"
    ):
        values["bfile"] = g.beancount_file_slug
    if endpoint in ["static", "index"]:
        return
コード例 #24
0
ファイル: engine.py プロジェクト: cuulee/appkernel
class AppKernelEngine(object):

    def __init__(self,
                 app_id,
                 app=None,
                 root_url='/',
                 log_level=logging.DEBUG,
                 cfg_dir=None,
                 development=None,
                 enable_defaults=False):
        """
        Initialiser of Flask Engine.
        :param app: the Flask App
        :type app: Flask
        :param root_url: the url where the service are exposed to.
        :type root_url: str
        :param log_level: the level of log
        :param cfg_dir: the directory containing the cfg.yml file. If not provided it will be taken from the command line or from current working dir;
        :param development: the system will be initialised in development mode if True. If None, it will try to read the value as command line parameter or default to false;
        :type log_level: logging
        """
        assert app_id is not None, 'The app_id must be provided'
        assert re.match('[A-Za-z0-9-_]',
                        app_id), 'The app_id must be a single word, no space or special characters except - or _ .'
        self.app = app or current_app
        assert self.app is not None, 'The Flask App must be provided as init parameter.'
        try:
            config.service_registry = {}
            self.before_request_functions = []
            self.after_request_functions = []
            self.app_id = app_id
            self.root_url = root_url
            self.__configure_flask_app()
            self.__init_web_layer()
            self.cmd_line_options = get_cmdline_options()
            self.cfg_dir = cfg_dir or self.cmd_line_options.get('cfg_dir')
            self.cfg_engine = CfgEngine(self.cfg_dir, optional=enable_defaults)
            config.cfg_engine = self.cfg_engine
            self.__init_babel()
            self.__init_cross_cutting_concerns()
            self.development = development or self.cmd_line_options.get('development')
            cwd = self.cmd_line_options.get('cwd')
            self.init_logger(log_folder=cwd, level=log_level)
            # -- initialisation
            # this can raise false positives if a bit of code running
            # longer than 1 seconds.
            # the timeout can be increased by adding the parameter:
            # resolution=3, where the value 3 represents 3 seconds.
            eventlet.debug.hub_blocking_detection(True, resolution=3)
            atexit.register(self.shutdown_hook)
            if hasattr(app, 'teardown_appcontext'):
                app.teardown_appcontext(self.teardown)
            else:
                app.teardown_request(self.teardown)
            # -- database host
            db_host = self.cfg_engine.get('appkernel.mongo.host') or 'localhost'
            db_name = self.cfg_engine.get('appkernel.mongo.db') or 'app'
            self.mongo_client = MongoClient(host=db_host)
            config.mongo_database = self.mongo_client[db_name]
        except (AppInitialisationError, AssertionError) as init_err:
            # print >> sys.stderr,
            self.app.logger.error(init_err.message)
            sys.exit(-1)

    def enable_security(self, authorisation_method=None):
        self.enable_pki()
        if not authorisation_method:
            authorisation_method = authorize_request
        self.add_before_request_function(authorisation_method)
        config.security_enabled = True
        return self

    def enable_pki(self):
        if not hasattr(self.app, 'public_key'):
            self.__init_crypto()

    def add_before_request_function(self, func):
        self.before_request_functions.append(func)

    def add_after_request_function(self, func):
        self.after_request_functions.append(func)

    def __init_cross_cutting_concerns(self):
        def create_function_chain_executor(chain):
            def function_chain_executor():
                for func in chain:
                    return func()

            return function_chain_executor

        # todo: journaling request responses
        # todo: rate limiting
        self.app.before_request(create_function_chain_executor(self.before_request_functions))
        # todo: add after request processor
        # self.app.after_request(create_function_chain_executor(self.after_request_functions))

    def __init_crypto(self):
        # https://stackoverflow.com/questions/29650495/how-to-verify-a-jwt-using-python-pyjwt-with-public-key
        with self.app.app_context():
            with open('{}/keys/appkernel.pem'.format(self.cfg_dir), "rb") as key_file:
                private_key = serialization.load_pem_private_key(
                    key_file.read(),
                    password=None,
                    backend=default_backend()
                )
                config.private_key = private_key
            with open('{}/keys/appkernel.pub'.format(self.cfg_dir), 'rb') as key_file:
                public_key = serialization.load_pem_public_key(
                    key_file.read(),
                    backend=default_backend()
                )
                config.public_key = public_key

    def __init_babel(self):
        self.babel = Babel(self.app)
        # translations = Translations.load('translations')
        # translations.merge(Translations.load())
        # todo: support for multiple plugins
        supported_languages = []
        for supported_lang in self.cfg_engine.get('appkernel.i18n.languages') or ['en-US']:
            supported_languages.append(supported_lang)
            if '-' in supported_lang:
                supported_languages.append(supported_lang.split('-')[0])

        def get_current_locale():
            with self.app.app_context():
                best_match = request.accept_languages.best_match(supported_languages, default='en')
                return best_match.replace('-', '_')

        self.babel.localeselector(get_current_locale)
        # catalogs = gettext.find('locale', 'locale', all=True)
        # self.logger.info('Using message catalogs: {}'.format(catalogs))

    @property
    def logger(self):
        return self.app.logger

    def run(self):
        self.app.logger.info('===== Starting {} ====='.format(self.app_id))
        self.app.run(debug=self.development)

    def shutdown_hook(self):
        if config.mongo_database:
            self.mongo_client.close()
        if self.app and self.app.logger:
            self.app.logger.info('======= Shutting Down {} ======='.format(self.app_id))

    def get_cmdline_options(self):
        # working dir is also available on: self.app.root_path
        argv = sys.argv[1:]
        opts, args = getopt.getopt(argv, 'c:dw:', ['config-dir=', 'development', 'working-dir='])
        # -- config directory
        config_dir_provided, config_dir_param = AppKernelEngine.is_option_provided(('-c', '--config-dir'), opts, args)
        cwd = os.path.dirname(os.path.realpath(sys.argv[0]))
        if config_dir_provided:
            cfg_dir = '{}/'.format(str(config_dir_param).rstrip('/'))
            cfg_dir = os.path.expanduser(cfg_dir)
            if not os.path.isdir(cfg_dir) or not os.access(cfg_dir, os.W_OK):
                raise AppInitialisationError('The config directory [{}] is not found/not writable.'.format(cfg_dir))
        else:
            cfg_dir = '{}/../'.format(cwd.rstrip('/'))

        # -- working directory
        working_dir_provided, working_dir_param = AppKernelEngine.is_option_provided(('-w', '--working-dir'), opts,
                                                                                     args)
        if working_dir_provided:
            cwd = os.path.expanduser('{}/'.format(str(config_dir_param).rstrip('/')))
            if not os.path.isdir(cwd) or not os.access(cwd, os.W_OK):
                raise AppInitialisationError('The working directory[{}] is not found/not writable.'.format(cwd))
        else:
            cwd = '{}/../'.format(cwd.rstrip('/'))
        development, param = AppKernelEngine.is_option_provided(('-d', '--development'), opts, args)
        return {
            'cfg_dir': cfg_dir,
            'development': development,
            'cwd': cwd
        }

    @staticmethod
    def is_option_provided(option_dict, opts, args):
        for opt, arg in opts:
            if opt in option_dict:
                return True, arg
        return False, ''

    def __configure_flask_app(self):
        if hasattr(self.app, 'teardown_appcontext'):
            self.app.teardown_appcontext(self.teardown)
        else:
            self.app.teardown_request(self.teardown)
        if not hasattr(self.app, 'extensions'):
            self.app.extensions = {}
        self.app.extensions['appkernel'] = self

    def __init_web_layer(self):
        self.app.json_encoder = AppKernelJSONEncoder
        self.app.register_error_handler(Exception, self.generic_error_handler)
        for code in default_exceptions.keys():
            # add a default error handler for everything is unhandled
            self.app.register_error_handler(code, self.generic_error_handler)

            def set_locale_on_request():
                g.locale = str(get_locale())

            self.app.before_request(set_locale_on_request)

    def init_logger(self, log_folder, level=logging.DEBUG):
        assert log_folder is not None, 'The log folder must be provided.'
        if self.development:
            formatter = logging.Formatter("%(levelname)s - %(message)s")
            handler = logging.StreamHandler()
            handler.setLevel(level)
            self._enable_werkzeug_logger(handler)
        else:
            # self.cfg_engine.get_value_for_section()
            # log_format = ' in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s'
            formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s:%(lineno)d - %(message)s")
            max_bytes = self.cfg_engine.get('appkernel.logging.max_size') or 10485760
            backup_count = self.cfg_engine.get('appkernel.logging.backup_count') or 3
            file_name = self.cfg_engine.get('appkernel.logging.file_name') or '{}.log'.format(self.app_id)
            handler = RotatingFileHandler('{}/{}.log'.format(log_folder, file_name), maxBytes=max_bytes,
                                          backupCount=backup_count)
            # handler = TimedRotatingFileHandler('logs/foo.log', when='midnight', interval=1)
            handler.setLevel(level)
        handler.setFormatter(formatter)
        self.app.logger.setLevel(level)
        self.app.logger.addHandler(handler)
        self.app.logger.info('Logger initialised')

    def _enable_werkzeug_logger(self, handler):
        logger = logging.getLogger('werkzeug')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(handler)

    def create_custom_error(self, code, message):
        return make_response(jsonify({'_type': MessageType.ErrorMessage.name, 'code': code, 'message': message}), code)

    def generic_error_handler(self, ex=None):
        """
        Takes a generic exception and returns a json error message which will be returned to the client
        :param ex:
        :return:
        """
        code = (ex.code if isinstance(ex, HTTPException) else 500)
        if ex:
            msg = '{}/{}'.format(ex.__class__.__name__, ex.description if isinstance(ex, HTTPException) else str(ex))
            self.logger.exception('generic error handler: {}/{}'.format(ex.__class__.__name__, str(ex)))
        else:
            msg = 'Generic server error.'
            self.logger.warn('generic error handler: {}/{}'.format(ex.__class__.__name__, str(ex)))
        return self.create_custom_error(code, msg)

    def teardown(self, exception):
        """
        context teardown based deallocation
        :param exception:
        :type exception: Exception
        :return:
        """
        if exception is not None:
            self.app.logger.warn(exception.message)

    def register(self, service_class, url_base=None, methods=['GET'], enable_hateoas=True):
        """

        :param service_class:
        :param url_base:
        :param methods:
        :param enable_hateoas:
        :return:
        :rtype: Service
        """
        assert issubclass(service_class, appkernel.Service), 'Only subclasses of Service can be registered.'
        service_class.set_app_engine(self, url_base or self.root_url, methods=methods, enable_hateoas=enable_hateoas)
        return service_class
コード例 #25
0
def i18n_init(app):
    """ initialize Flask-Babel """
    babel = Babel(app)
    babel.localeselector(get_locale)
    babel.timezoneselector(get_timezone)
コード例 #26
0
ファイル: flask_app.py プロジェクト: Br3nda/ckan
def make_flask_stack(conf, **app_conf):
    """ This has to pass the flask app through all the same middleware that
    Pylons used """

    root = os.path.dirname(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    debug = asbool(app_conf.get('debug', app_conf.get('DEBUG', False)))
    testing = asbool(app_conf.get('testing', app_conf.get('TESTING', False)))

    app = flask_app = CKANFlask(__name__)
    app.debug = debug
    app.testing = testing
    app.template_folder = os.path.join(root, 'templates')
    app.app_ctx_globals_class = CKAN_AppCtxGlobals
    app.url_rule_class = CKAN_Rule
    app.jinja_loader = ChoiceLoader([
        app.jinja_loader,
        CkanextTemplateLoader()
    ])

    # Update Flask config with the CKAN values. We use the common config
    # object as values might have been modified on `load_environment`
    if config:
        app.config.update(config)
    else:
        app.config.update(conf)
        app.config.update(app_conf)

    # Do all the Flask-specific stuff before adding other middlewares

    # Secret key needed for flask-debug-toolbar and sessions
    if not app.config.get('SECRET_KEY'):
        app.config['SECRET_KEY'] = config.get('beaker.session.secret')
    if not app.config.get('SECRET_KEY'):
        raise RuntimeError(u'You must provide a value for the secret key'
                           ' with the SECRET_KEY config option')

    if debug:
        from flask_debugtoolbar import DebugToolbarExtension
        app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
        DebugToolbarExtension(app)

    # Use Beaker as the Flask session interface
    class BeakerSessionInterface(SessionInterface):
        def open_session(self, app, request):
            if 'beaker.session' in request.environ:
                return request.environ['beaker.session']

        def save_session(self, app, session, response):
            session.save()

    namespace = 'beaker.session.'
    session_opts = dict([(k.replace('beaker.', ''), v)
                        for k, v in config.iteritems()
                        if k.startswith(namespace)])
    if (not session_opts.get('session.data_dir') and
            session_opts.get('session.type', 'file') == 'file'):
        cache_dir = app_conf.get('cache_dir') or app_conf.get('cache.dir')
        session_opts['session.data_dir'] = '{data_dir}/sessions'.format(
                data_dir=cache_dir)

    app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts)
    app.session_interface = BeakerSessionInterface()

    # Add Jinja2 extensions and filters
    extensions = [
        'jinja2.ext.do', 'jinja2.ext.with_',
        jinja_extensions.SnippetExtension,
        jinja_extensions.CkanExtend,
        jinja_extensions.CkanInternationalizationExtension,
        jinja_extensions.LinkForExtension,
        jinja_extensions.ResourceExtension,
        jinja_extensions.UrlForStaticExtension,
        jinja_extensions.UrlForExtension
    ]
    for extension in extensions:
        app.jinja_env.add_extension(extension)
    app.jinja_env.filters['empty_and_escape'] = \
        jinja_extensions.empty_and_escape

    # Common handlers for all requests
    app.before_request(ckan_before_request)
    app.after_request(ckan_after_request)

    # Template context processors
    app.context_processor(helper_functions)
    app.context_processor(c_object)

    @app.context_processor
    def ungettext_alias():
        u'''
        Provide `ungettext` as an alias of `ngettext` for backwards
        compatibility
        '''
        return dict(ungettext=ungettext)

    # Babel
    app.config[u'BABEL_TRANSLATION_DIRECTORIES'] = os.path.join(root, u'i18n')
    app.config[u'BABEL_DOMAIN'] = 'ckan'

    babel = Babel(app)

    babel.localeselector(get_locale)

    @app.route('/hello', methods=['GET'])
    def hello_world():
        return 'Hello World, this is served by Flask'

    @app.route('/hello', methods=['POST'])
    def hello_world_post():
        return 'Hello World, this was posted to Flask'

    # Auto-register all blueprints defined in the `views` folder
    _register_core_blueprints(app)

    # Set up each IBlueprint extension as a Flask Blueprint
    for plugin in PluginImplementations(IBlueprint):
        if hasattr(plugin, 'get_blueprint'):
            app.register_extension_blueprint(plugin.get_blueprint())

    # Start other middleware
    for plugin in PluginImplementations(IMiddleware):
        app = plugin.make_middleware(app, config)

    # Fanstatic
    if debug:
        fanstatic_config = {
            'versioning': True,
            'recompute_hashes': True,
            'minified': False,
            'bottom': True,
            'bundle': False,
        }
    else:
        fanstatic_config = {
            'versioning': True,
            'recompute_hashes': False,
            'minified': True,
            'bottom': True,
            'bundle': True,
        }
    root_path = config.get('ckan.root_path', None)
    if root_path:
        root_path = re.sub('/{{LANG}}', '', root_path)
        fanstatic_config['base_url'] = root_path
    app = Fanstatic(app, **fanstatic_config)

    for plugin in PluginImplementations(IMiddleware):
        try:
            app = plugin.make_error_log_middleware(app, config)
        except AttributeError:
            log.critical('Middleware class {0} is missing the method'
                         'make_error_log_middleware.'
                         .format(plugin.__class__.__name__))

    # Initialize repoze.who
    who_parser = WhoConfig(conf['here'])
    who_parser.parse(open(app_conf['who.config_file']))

    app = PluggableAuthenticationMiddleware(
        app,
        who_parser.identifiers,
        who_parser.authenticators,
        who_parser.challengers,
        who_parser.mdproviders,
        who_parser.request_classifier,
        who_parser.challenge_decider,
        logging.getLogger('repoze.who'),
        logging.WARN,  # ignored
        who_parser.remote_user_key
    )

    # Update the main CKAN config object with the Flask specific keys
    # that were set here or autogenerated
    flask_config_keys = set(flask_app.config.keys()) - set(config.keys())
    for key in flask_config_keys:
        config[key] = flask_app.config[key]

    # Add a reference to the actual Flask app so it's easier to access
    app._wsgi_app = flask_app

    return app
コード例 #27
0
ファイル: flask_app.py プロジェクト: HighwayThree/ckan
def make_flask_stack(conf, **app_conf):
    """ This has to pass the flask app through all the same middleware that
    Pylons used """

    root = os.path.dirname(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    debug = asbool(app_conf.get('debug', app_conf.get('DEBUG', False)))
    testing = asbool(app_conf.get('testing', app_conf.get('TESTING', False)))

    app = flask_app = CKANFlask(__name__)
    app.debug = debug
    app.testing = testing
    app.template_folder = os.path.join(root, 'templates')
    app.app_ctx_globals_class = CKAN_AppCtxGlobals
    app.url_rule_class = CKAN_Rule

    # Update Flask config with the CKAN values. We use the common config
    # object as values might have been modified on `load_environment`
    if config:
        app.config.update(config)
    else:
        app.config.update(conf)
        app.config.update(app_conf)

    # Do all the Flask-specific stuff before adding other middlewares

    # Secret key needed for flask-debug-toolbar and sessions
    if not app.config.get('SECRET_KEY'):
        app.config['SECRET_KEY'] = config.get('beaker.session.secret')
    if not app.config.get('SECRET_KEY'):
        raise RuntimeError(u'You must provide a value for the secret key'
                           ' with the SECRET_KEY config option')

    if debug:
        from flask_debugtoolbar import DebugToolbarExtension
        app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
        DebugToolbarExtension(app)

    # Use Beaker as the Flask session interface
    class BeakerSessionInterface(SessionInterface):
        def open_session(self, app, request):
            if 'beaker.session' in request.environ:
                return request.environ['beaker.session']

        def save_session(self, app, session, response):
            session.save()

    namespace = 'beaker.session.'
    session_opts = dict([(k.replace('beaker.', ''), v)
                        for k, v in config.iteritems()
                        if k.startswith(namespace)])
    if (not session_opts.get('session.data_dir') and
            session_opts.get('session.type', 'file') == 'file'):
        cache_dir = app_conf.get('cache_dir') or app_conf.get('cache.dir')
        session_opts['session.data_dir'] = '{data_dir}/sessions'.format(
                data_dir=cache_dir)

    app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts)
    app.session_interface = BeakerSessionInterface()

    # Add Jinja2 extensions and filters
    extensions = [
        'jinja2.ext.do', 'jinja2.ext.with_',
        jinja_extensions.SnippetExtension,
        jinja_extensions.CkanExtend,
        jinja_extensions.CkanInternationalizationExtension,
        jinja_extensions.LinkForExtension,
        jinja_extensions.ResourceExtension,
        jinja_extensions.UrlForStaticExtension,
        jinja_extensions.UrlForExtension
    ]
    for extension in extensions:
        app.jinja_env.add_extension(extension)
    app.jinja_env.filters['empty_and_escape'] = \
        jinja_extensions.empty_and_escape

    # Common handlers for all requests
    app.before_request(ckan_before_request)
    app.after_request(ckan_after_request)

    # Template context processors
    app.context_processor(helper_functions)
    app.context_processor(c_object)

    @app.context_processor
    def ungettext_alias():
        u'''
        Provide `ungettext` as an alias of `ngettext` for backwards
        compatibility
        '''
        return dict(ungettext=ungettext)

    # Babel
    app.config[u'BABEL_TRANSLATION_DIRECTORIES'] = os.path.join(root, u'i18n')
    app.config[u'BABEL_DOMAIN'] = 'ckan'

    babel = Babel(app)

    babel.localeselector(get_locale)

    @app.route('/hello', methods=['GET'])
    def hello_world():
        return 'Hello World, this is served by Flask'

    @app.route('/hello', methods=['POST'])
    def hello_world_post():
        return 'Hello World, this was posted to Flask'

    # Auto-register all blueprints defined in the `views` folder
    _register_core_blueprints(app)

    # Set up each IBlueprint extension as a Flask Blueprint
    for plugin in PluginImplementations(IBlueprint):
        if hasattr(plugin, 'get_blueprint'):
            app.register_extension_blueprint(plugin.get_blueprint())

    # Start other middleware
    for plugin in PluginImplementations(IMiddleware):
        app = plugin.make_middleware(app, config)

    # Fanstatic
    if debug:
        fanstatic_config = {
            'versioning': True,
            'recompute_hashes': True,
            'minified': False,
            'bottom': True,
            'bundle': False,
        }
    else:
        fanstatic_config = {
            'versioning': True,
            'recompute_hashes': False,
            'minified': True,
            'bottom': True,
            'bundle': True,
        }
    root_path = config.get('ckan.root_path', None)
    if root_path:
        root_path = re.sub('/{{LANG}}', '', root_path)
        fanstatic_config['base_url'] = root_path
    app = Fanstatic(app, **fanstatic_config)

    for plugin in PluginImplementations(IMiddleware):
        try:
            app = plugin.make_error_log_middleware(app, config)
        except AttributeError:
            log.critical('Middleware class {0} is missing the method'
                         'make_error_log_middleware.'
                         .format(plugin.__class__.__name__))

    # Initialize repoze.who
    who_parser = WhoConfig(conf['here'])
    who_parser.parse(open(app_conf['who.config_file']))

    app = PluggableAuthenticationMiddleware(
        app,
        who_parser.identifiers,
        who_parser.authenticators,
        who_parser.challengers,
        who_parser.mdproviders,
        who_parser.request_classifier,
        who_parser.challenge_decider,
        logging.getLogger('repoze.who'),
        logging.WARN,  # ignored
        who_parser.remote_user_key
    )

    # Update the main CKAN config object with the Flask specific keys
    # that were set here or autogenerated
    flask_config_keys = set(flask_app.config.keys()) - set(config.keys())
    for key in flask_config_keys:
        config[key] = flask_app.config[key]

    # Add a reference to the actual Flask app so it's easier to access
    app._wsgi_app = flask_app

    return app
コード例 #28
0
def init(babel: Babel) -> None:
    LANGUAGES.extend([str(locale) for locale in babel.list_translations()])
    babel.localeselector(get_locale)