Example #1
0
def configure_application(module_name, config, root, settings, configured):
    if module_name in configured:
        return

    module = resolve_dotted_name(module_name)
    if hasattr(module, 'app_settings') and app_settings != module.app_settings:
        # load dependencies if necessary
        for dependency in module.app_settings.get('applications') or []:
            if dependency not in configured and module_name != dependency:
                configure_application(dependency, config, root, settings, configured)

    config.begin(module_name)
    load_application(module, root, settings)
    config.execute_actions()
    config.commit()

    configured.append(module_name)
Example #2
0
def make_app(config_file=None, settings=None, loop=None, server_app=None):
    app_settings.update(_delayed_default_settings)

    if loop is None:
        loop = asyncio.get_event_loop()

    loop.set_task_factory(aiotask_context.task_factory)

    if config_file is not None:
        with open(config_file, 'r') as config:
            settings = json.load(config)
    elif settings is None:
        raise Exception('Neither configuration or settings')

    # Create root Application
    root = ApplicationRoot(config_file)
    provide_utility(root, IApplication, 'root')

    # Initialize global (threadlocal) ZCA configuration
    config = root.config = ConfigurationMachine()

    import guillotina
    import guillotina.db.factory
    import guillotina.db.writer
    import guillotina.db.db
    configure.scan('guillotina.translation')
    configure.scan('guillotina.renderers')
    configure.scan('guillotina.api')
    configure.scan('guillotina.content')
    configure.scan('guillotina.registry')
    configure.scan('guillotina.auth')
    configure.scan('guillotina.json')
    configure.scan('guillotina.behaviors')
    configure.scan('guillotina.languages')
    configure.scan('guillotina.permissions')
    configure.scan('guillotina.security.security_local')
    configure.scan('guillotina.security.policy')
    configure.scan('guillotina.auth.participation')
    configure.scan('guillotina.catalog.index')
    configure.scan('guillotina.catalog.catalog')
    configure.scan('guillotina.framing')
    configure.scan('guillotina.files')
    configure.scan('guillotina.annotations')
    configure.scan('guillotina.constraintypes')
    configure.scan('guillotina.subscribers')
    configure.scan('guillotina.db.strategies')
    configure.scan('guillotina.db.cache')
    load_application(guillotina, root, settings)
    config.execute_actions()
    config.commit()

    for module_name in settings.get('applications', []):
        config.begin(module_name)
        load_application(resolve_dotted_name(module_name), root, settings)
        config.execute_actions()
        config.commit()

    # XXX we clear now to save some memory
    # it's unclear to me if this is necesary or not but it seems to me that
    # we don't need things registered in both components AND here.
    configure.clear()

    # update *after* plugins loaded
    update_app_settings(settings)

    if 'logging' in app_settings:
        logging.config.dictConfig(app_settings['logging'])

    # Make and initialize aiohttp app
    if server_app is None:
        server_app = make_aiohttp_application()
    root.app = server_app
    server_app.root = root
    server_app.config = config

    content_type = ContentNegotiatorUtility('content_type',
                                            app_settings['renderers'].keys())
    language = ContentNegotiatorUtility('language',
                                        app_settings['languages'].keys())

    provide_utility(content_type, IContentNegotiation, 'content_type')
    provide_utility(language, IContentNegotiation, 'language')

    for database in app_settings['databases']:
        for key, dbconfig in database.items():
            factory = get_utility(IDatabaseConfigurationFactory,
                                  name=dbconfig['storage'])
            if asyncio.iscoroutinefunction(factory):
                future = asyncio.ensure_future(factory(key, dbconfig,
                                                       server_app),
                                               loop=loop)

                loop.run_until_complete(future)
                root[key] = future.result()
            else:
                root[key] = factory(key, dbconfig)

    for key, file_path in list_or_dict_items(app_settings['static']):
        path = resolve_path(file_path).resolve()
        if not path.exists():
            raise Exception('Invalid static directory {}'.format(file_path))
        if path.is_dir():
            root[key] = StaticDirectory(path)
        else:
            root[key] = StaticFile(path)
    for key, file_path in list_or_dict_items(app_settings['jsapps']):
        path = resolve_path(file_path).resolve()
        if not path.exists() or not path.is_dir():
            raise Exception('Invalid jsapps directory {}'.format(file_path))
        root[key] = JavaScriptApplication(path)

    root.set_root_user(app_settings['root_user'])

    if RSA is not None and not app_settings.get('rsa'):
        key = RSA.generate(2048)
        pub_jwk = {'k': key.publickey().exportKey('PEM')}
        priv_jwk = {'k': key.exportKey('PEM')}
        app_settings['rsa'] = {'pub': pub_jwk, 'priv': priv_jwk}

    # Set router root
    server_app.router.set_root(root)

    for utility in get_all_utilities_registered_for(IAsyncUtility):
        # In case there is Utilties that are registered
        if hasattr(utility, 'initialize'):
            task = asyncio.ensure_future(lazy_apply(utility.initialize,
                                                    app=server_app),
                                         loop=loop)
            root.add_async_task(utility, task, {})
        else:
            logger.warn(f'No initialize method found on {utility} object')

    server_app.on_cleanup.append(close_utilities)

    for util in app_settings['utilities']:
        root.add_async_utility(util, loop=loop)

    # Load cached Schemas
    load_cached_schema()

    optimize_settings(app_settings)

    return server_app