pyramid_cubicweb/__init__.py
author Christophe de Vienne <christophe@unlish.com>
Sat, 03 Jan 2015 16:51:32 +0100
changeset 11535 dd875009cc47
parent 11534 ceb1a5baca4f
child 11537 caf268942436
permissions -rw-r--r--
[profile] Add a profiling tool

import os
import wsgicors

from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
from pyramid.config import Configurator
from pyramid.settings import asbool, aslist

try:
    from configparser import SafeConfigParser
except ImportError:
    from ConfigParser import SafeConfigParser


def make_cubicweb_application(cwconfig):
    """
    Create a pyramid-based CubicWeb instance from a cubicweb configuration.

    It is initialy meant to be used by the 'pyramid' command of cubicweb-ctl.
    """
    settings_filenames = [os.path.join(cwconfig.apphome, 'pyramid.ini')]

    settings = {}

    if cwconfig.debugmode:
        settings_filenames.insert(
            0, os.path.join(cwconfig.apphome, 'pyramid-debug.ini'))

        settings.update({
            'pyramid.debug_authorization': True,
            'pyramid.debug_notfound': True,
            'pyramid.debug_routematch': True,
        })

    for fname in settings_filenames:
        if os.path.exists(fname):
            cp = SafeConfigParser()
            cp.read(fname)
            settings.update(cp.items('main'))
            break

    config = Configurator(settings=settings)
    if cwconfig.debugmode:
        config.include('pyramid_debugtoolbar')
    config.registry['cubicweb.config'] = cwconfig
    config.registry['cubicweb.repository'] = repo = cwconfig.repository()
    config.registry['cubicweb.registry'] = repo.vreg

    if asbool(config.registry.settings.get('cubicweb.defaults', True)):
        config.include('pyramid_cubicweb.defaults')

    for name in aslist(config.registry.settings.get('cubicweb.includes')):
        config.include(name)

    config.include('pyramid_cubicweb.core')

    if asbool(config.registry.settings.get('cubicweb.bwcompat', True)):
        config.include('pyramid_cubicweb.bwcompat')
    return config


def wsgi_application_from_cwconfig(
        cwconfig,
        profile=False, profile_output=None, profile_dump_every=None):
    config = make_cubicweb_application(cwconfig)
    profile = profile or asbool(config.registry.settings.get(
        'cubicweb.profile.enable', False))
    if profile:
        config.add_route('profile_ping', '_profile/ping')
        config.add_route('profile_cnx', '_profile/cnx')
        config.scan('pyramid_cubicweb.profile')
    app = config.make_wsgi_app()
    # This replaces completely web/cors.py, which is not used by
    # pyramid_cubicweb anymore
    app = wsgicors.CORS(
        app,
        origin=' '.join(cwconfig['access-control-allow-origin']),
        headers=cwconfig['access-control-allow-headers'],
        methods=cwconfig['access-control-allow-methods'],
        credentials='true')

    if profile:
        from pyramid_cubicweb.profile import wsgi_profile
        filename = profile_output or config.registry.settings.get(
            'cubicweb.profile.output', 'program.prof')
        dump_every = profile_dump_every or config.registry.settings.get(
            'cubicweb.profile.dump_every', 100)
        app = wsgi_profile(app, filename=filename, dump_every=dump_every)
    return app


def wsgi_application(instance_name=None, debug=None):
    if instance_name is None:
        instance_name = os.environ.get('CW_INSTANCE')
    if debug is None:
        debug = 'CW_DEBUG' in os.environ

    cwconfig = cwcfg.config_for(instance_name, debugmode=debug)

    return wsgi_application_from_cwconfig(cwconfig)