cubicweb/pyramid/__init__.py
changeset 11631 faf279e33298
parent 11623 b6f6737d4823
child 11702 be23c3813bbf
equal deleted inserted replaced
11478:1817f8946c22 11631:faf279e33298
       
     1 import os
       
     2 from warnings import warn
       
     3 import wsgicors
       
     4 
       
     5 from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
       
     6 from pyramid.config import Configurator
       
     7 from pyramid.settings import asbool, aslist
       
     8 
       
     9 try:
       
    10     from configparser import SafeConfigParser
       
    11 except ImportError:
       
    12     from ConfigParser import SafeConfigParser
       
    13 
       
    14 
       
    15 def make_cubicweb_application(cwconfig, settings=None):
       
    16     """
       
    17     Create a pyramid-based CubicWeb instance from a cubicweb configuration.
       
    18 
       
    19     It is initialy meant to be used by the 'pyramid' command of cubicweb-ctl.
       
    20 
       
    21     :param cwconfig: A CubicWeb configuration
       
    22     :returns: A Pyramid config object
       
    23     """
       
    24     settings = dict(settings) if settings else {}
       
    25     settings.update(settings_from_cwconfig(cwconfig))
       
    26     config = Configurator(settings=settings)
       
    27     config.registry['cubicweb.config'] = cwconfig
       
    28     config.include('cubicweb.pyramid')
       
    29     return config
       
    30 
       
    31 def settings_from_cwconfig(cwconfig):
       
    32     '''
       
    33     Extract settings from pyramid.ini and pyramid-debug.ini (if in debug)
       
    34 
       
    35     Can be used to configure middleware WSGI with settings from pyramid.ini files
       
    36 
       
    37     :param cwconfig: A CubicWeb configuration
       
    38     :returns: A settings dictionnary
       
    39     '''
       
    40     settings_filenames = [os.path.join(cwconfig.apphome, 'pyramid.ini')]
       
    41     settings = {}
       
    42     if cwconfig.debugmode:
       
    43         settings_filenames.insert(
       
    44             0, os.path.join(cwconfig.apphome, 'pyramid-debug.ini'))
       
    45     
       
    46         settings.update({
       
    47             'pyramid.debug_authorization': True,
       
    48             'pyramid.debug_notfound': True,
       
    49             'pyramid.debug_routematch': True,
       
    50             'pyramid.reload_templates': True,
       
    51         })
       
    52     
       
    53     for fname in settings_filenames:
       
    54         if os.path.exists(fname):
       
    55             cp = SafeConfigParser()
       
    56             cp.read(fname)
       
    57             settings.update(cp.items('main'))
       
    58             break
       
    59     
       
    60     return settings
       
    61 
       
    62 
       
    63 def wsgi_application_from_cwconfig(
       
    64         cwconfig,
       
    65         profile=False, profile_output=None, profile_dump_every=None):
       
    66     """ Build a WSGI application from a cubicweb configuration
       
    67 
       
    68     :param cwconfig: A CubicWeb configuration
       
    69     :param profile: Enable profiling. See :ref:`profiling`.
       
    70     :param profile_output: Profiling output filename. See :ref:`profiling`.
       
    71     :param profile_dump_every: Profiling number of requests before dumping the
       
    72                                stats. See :ref:`profiling`.
       
    73 
       
    74     :returns: A fully operationnal WSGI application
       
    75     """
       
    76     config = make_cubicweb_application(cwconfig)
       
    77     profile = profile or asbool(config.registry.settings.get(
       
    78         'cubicweb.profile.enable', False))
       
    79     if profile:
       
    80         config.add_route('profile_ping', '_profile/ping')
       
    81         config.add_route('profile_cnx', '_profile/cnx')
       
    82         config.scan('cubicweb.pyramid.profile')
       
    83     app = config.make_wsgi_app()
       
    84     # This replaces completely web/cors.py, which is not used by
       
    85     # cubicweb.pyramid anymore
       
    86     app = wsgicors.CORS(
       
    87         app,
       
    88         origin=' '.join(cwconfig['access-control-allow-origin']),
       
    89         headers=', '.join(cwconfig['access-control-allow-headers']),
       
    90         methods=', '.join(cwconfig['access-control-allow-methods']),
       
    91         credentials='true')
       
    92 
       
    93     if profile:
       
    94         from cubicweb.pyramid.profile import wsgi_profile
       
    95         filename = profile_output or config.registry.settings.get(
       
    96             'cubicweb.profile.output', 'program.prof')
       
    97         dump_every = profile_dump_every or config.registry.settings.get(
       
    98             'cubicweb.profile.dump_every', 100)
       
    99         app = wsgi_profile(app, filename=filename, dump_every=dump_every)
       
   100     return app
       
   101 
       
   102 
       
   103 def wsgi_application(instance_name=None, debug=None):
       
   104     """ Build a WSGI application from a cubicweb instance name
       
   105 
       
   106     :param instance_name: Name of the cubicweb instance (optional). If not
       
   107                           provided, :envvar:`CW_INSTANCE` must exists.
       
   108     :param debug: Enable/disable the debug mode. If defined to True or False,
       
   109                   overrides :envvar:`CW_DEBUG`.
       
   110 
       
   111     The following environment variables are used if they exist:
       
   112 
       
   113     .. envvar:: CW_INSTANCE
       
   114 
       
   115         A CubicWeb instance name.
       
   116 
       
   117     .. envvar:: CW_DEBUG
       
   118 
       
   119         If defined, the debugmode is enabled.
       
   120 
       
   121     The function can be used as an entry-point for third-party wsgi containers.
       
   122     Below is a sample uswgi configuration file:
       
   123 
       
   124     .. code-block:: ini
       
   125 
       
   126         [uwsgi]
       
   127         http = 127.0.1.1:8080
       
   128         env = CW_INSTANCE=myinstance
       
   129         env = CW_DEBUG=1
       
   130         module = cubicweb.pyramid:wsgi_application()
       
   131         virtualenv = /home/user/.virtualenvs/myvirtualenv
       
   132         processes = 1
       
   133         threads = 8
       
   134         stats = 127.0.0.1:9191
       
   135         plugins = http,python
       
   136 
       
   137     """
       
   138     if instance_name is None:
       
   139         instance_name = os.environ['CW_INSTANCE']
       
   140     if debug is None:
       
   141         debug = 'CW_DEBUG' in os.environ
       
   142 
       
   143     cwconfig = cwcfg.config_for(instance_name, debugmode=debug)
       
   144 
       
   145     return wsgi_application_from_cwconfig(cwconfig)
       
   146 
       
   147 
       
   148 def includeme(config):
       
   149     """Set-up a CubicWeb instance.
       
   150 
       
   151     The CubicWeb instance can be set in several ways:
       
   152 
       
   153     -   Provide an already loaded CubicWeb config instance in the registry:
       
   154 
       
   155         .. code-block:: python
       
   156 
       
   157             config.registry['cubicweb.config'] = your_config_instance
       
   158 
       
   159     -   Provide an instance name in the pyramid settings with
       
   160         :confval:`cubicweb.instance`.
       
   161 
       
   162     """
       
   163     cwconfig = config.registry.get('cubicweb.config')
       
   164 
       
   165     if cwconfig is None:
       
   166         debugmode = asbool(
       
   167             config.registry.settings.get('cubicweb.debug', False))
       
   168         cwconfig = cwcfg.config_for(
       
   169             config.registry.settings['cubicweb.instance'], debugmode=debugmode)
       
   170         config.registry['cubicweb.config'] = cwconfig
       
   171 
       
   172     if cwconfig.debugmode:
       
   173         try:
       
   174             config.include('pyramid_debugtoolbar')
       
   175         except ImportError:
       
   176             warn('pyramid_debugtoolbar package not available, install it to '
       
   177                  'get UI debug features', RuntimeWarning)
       
   178 
       
   179     config.registry['cubicweb.repository'] = repo = cwconfig.repository()
       
   180     config.registry['cubicweb.registry'] = repo.vreg
       
   181 
       
   182     if asbool(config.registry.settings.get('cubicweb.defaults', True)):
       
   183         config.include('cubicweb.pyramid.defaults')
       
   184 
       
   185     for name in aslist(config.registry.settings.get('cubicweb.includes', [])):
       
   186         config.include(name)
       
   187 
       
   188     config.include('cubicweb.pyramid.tools')
       
   189     config.include('cubicweb.pyramid.predicates')
       
   190     config.include('cubicweb.pyramid.core')
       
   191 
       
   192     if asbool(config.registry.settings.get('cubicweb.bwcompat', True)):
       
   193         config.include('cubicweb.pyramid.bwcompat')