|
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') |