Source code for portal_web

# For copyright and license terms, see COPYRIGHT.rst (top level of repository)
# Repository: https://github.com/C3S/portal_web

"""
Main module for the pyramid app.
"""

import os
import logging
from logging.config import fileConfig

from pyramid.config import Configurator
from pyramid_beaker import session_factory_from_settings

from .config import (
    replace_environment_vars,
    get_plugins,
    notfound
)
from .security import SecurityPolicy
from .models import Tdb
from .resources import (
    WebRootFactory,
    ApiRootFactory
)

log = logging.getLogger(__name__)


[docs] def main(global_config, **settings): """ Configures and creates the app. Handles configuration of - debugpy debugging - app config - tryton database - session - policies - subscribers - route predicates - view predicates - request methods - translation directories - logging - root factories - resources - registry - views Contains the main logic of the plugin system by including settings, translation directories, logging configuration, views, ressources and registry information of the plugins in a well defined order. Args: global_config (dict): Parsed [DEFAULT] section of .ini file. **settings (dict): Parsed [app:main] section of .ini file. Returns: obj: a Pyramid WSGI application. """ # get environment environment = os.environ.get('ENVIRONMENT') # get plugin configuration plugins = get_plugins(settings) # update portal settings with plugin settings and replace environment vars for priority in sorted(plugins, reverse=True): settings.update(plugins[priority]['settings']) settings = replace_environment_vars(settings) # init app config config = Configurator(settings=settings) # configure tryton database Tdb._db = settings['tryton.database'] Tdb._company = settings['tryton.company'] Tdb._user = settings['tryton.user'] Tdb._configfile = settings['tryton.configfile'] Tdb.init() # configure session config.set_session_factory(factory=session_factory_from_settings(settings)) # configure policies config.set_security_policy( SecurityPolicy(settings['authentication.secret'])) config.set_default_permission('administrator') # configure subscribers config.add_subscriber( subscriber='.config.add_templates', iface='pyramid.events.BeforeRender') config.add_subscriber( subscriber='.config.add_helpers', iface='pyramid.events.BeforeRender') config.add_subscriber( subscriber='.config.add_locale', iface='pyramid.events.NewRequest') config.add_subscriber( subscriber='.config.start_db_transaction', iface='pyramid.events.BeforeTraversal') config.add_subscriber( subscriber='.config.context_found', iface='pyramid.events.ContextFound') config.add_subscriber( subscriber='.config.stop_db_transaction', iface='pyramid.events.NewRequest') if settings['env'] in ['development', 'staging']: config.add_subscriber( subscriber='.config.debug_request', iface='pyramid.events.NewRequest') config.add_subscriber( subscriber='.config.debug_context', iface='pyramid.events.ContextFound') config.add_subscriber( subscriber='.config.debug_response', iface='pyramid.events.NewResponse') # configure predicates config.add_route_predicate( name='environment', factory='.config.Environment') config.add_view_predicate( name='environment', factory='.config.Environment') # configure request methods config.add_request_method( callable='.config.web_user', name='web_user', reify=True) config.add_request_method( callable='.config.party', name='party', reify=True) config.add_request_method( callable='.config.user', name='user', reify=True) config.add_request_method( callable='.config.roles', name='roles', reify=True) # configure translation directories for portal and plugins config.add_translation_dirs( 'colander:locale/', 'deform:locale/', 'portal_web:locale/') for priority in sorted(plugins): translation_dir = os.path.join( plugins[priority]['path'], plugins[priority]['name'], 'locale') if os.path.isdir(translation_dir): config.add_translation_dirs(translation_dir) # configure logging for portal and plugins for priority in sorted(plugins): fileConfig( plugins[priority]['path'] + '/' + environment + '.ini', disable_existing_loggers=False) # commit config with basic settings config.commit() # not found view (404 Error) config.add_notfound_view(notfound) # configure mailer if int(settings['mail.to_real_world']): config.include('pyramid_mailer') else: config.include('pyramid_mailer.testing') # enable debugpy debugging (open port 52000 for portal and 52001 for api!) if int(settings['debugger.debugpy']): debugging_port = False if settings['service'] == 'webgui': debugging_port = 52000 if settings['service'] == 'webapi': debugging_port = 52001 if debugging_port: log.debug(settings['service'] + " debugger listening to port " + str(debugging_port)) try: import debugpy # unconditional import breaks test coverage debugpy.listen(("0.0.0.0", debugging_port)) except Exception as ex: if hasattr(ex, 'message'): log.debug(ex.message) else: log.debug('debugpy debugging not possible: ' + ex.message) # configure webfrontend for portal and plugins if settings['service'] == 'webgui': # web root factory config.set_root_factory(factory=WebRootFactory) # web resources config.include('.includes.web_resources') for priority in sorted(plugins): config.include(plugins[priority]['name']+'.includes.web_resources') # web registry config.include('.includes.web_registry') for priority in sorted(plugins): config.include(plugins[priority]['name']+'.includes.web_registry') # web views for priority in sorted(plugins, reverse=True): config.include(plugins[priority]['name'] + '.includes.web_views') config.include('.includes.web_views') # api views if settings['api.in_web'] == 'true': config.include('cornice') for priority in sorted(plugins, reverse=True): config.include( plugins[priority]['name'] + '.includes.api_views', route_prefix=settings['api.in_web_path']) config.include( '.includes.api_views', route_prefix=settings['api.in_web_path']) # configure api for portal and plugins if settings['service'] == 'webapi': config.include('cornice') config.include('cornice_swagger') # api root factory config.set_root_factory(factory=ApiRootFactory) # api views for priority in sorted(plugins, reverse=True): config.include(plugins[priority]['name'] + '.includes.api_views') config.include('.includes.api_views') return config.make_wsgi_app()