1
"""Configuration object and defaults setup
3
The PylonsConfig object is initialized in pylons projects inside the
4
:file:`config/environment.py` module. Importing the :data:`config`
5
object from module causes the PylonsConfig object to be created, and
6
setup in app-safe manner so that multiple apps being setup avoid
9
After importing :data:`config`, the project should then call
10
:meth:`~PylonsConfig.init_app` with the appropriate options to setup
11
the configuration. In the config data passed with
12
:meth:`~PylonsConfig.init_app`, various defaults are set use with Paste
20
from paste.config import DispatchingConfig
21
from paste.deploy.converters import asbool
22
from webhelpers.mimehelper import MIMETypes
25
default_template_engine = 'mako'
27
request_defaults = dict(charset='utf-8', errors='replace',
28
decode_param_names=False, language='en-us')
29
response_defaults = dict(content_type='text/html',
30
charset='utf-8', errors='strict',
31
headers={'Cache-Control': 'no-cache',
32
'Pragma': 'no-cache'})
34
log = logging.getLogger(__name__)
37
config = DispatchingConfig()
39
class PylonsConfig(dict):
40
"""Pylons configuration object
42
The Pylons configuration object is a per-application instance
43
object that retains the information regarding the global and app
44
conf's as well as per-application instance specific data such as
45
the mapper, and the paths for this instance.
47
The config object is available in your application as the Pylons
48
global :data:`pylons.config`. For example::
50
from pylons import config
52
template_paths = config['pylons.paths']['templates']
54
There's several useful keys of the config object most people will
58
A dict of absolute paths that were defined in the applications
59
``config/environment.py`` module.
60
``pylons.environ_config``
61
Dict of environ keys for where in the environ to pickup various
62
objects for registering with Pylons. If these are present then
63
PylonsApp will use them from environ rather than using default
64
middleware from Beaker. Valid keys are: ``session, cache``
65
``pylons.strict_tmpl_context``
66
Whether or not the ``tmpl_context`` object should throw an
67
attribute error when access is attempted to an attribute that
68
doesn't exist. Defaults to True.
69
``pylons.tmpl_context_attach_args``
70
Whethor or not Routes variables should automatically be
71
attached to the tmpl_context object when specified in a
73
``pylons.request_options``
74
A dict of Content-Type related default settings for new
75
instances of :class:`~pylons.controllers.util.Request`. May
76
contain the values ``charset`` and ``errors`` and
77
``decode_param_names``. Overrides the Pylons default values
78
specified by the ``request_defaults`` dict.
79
``pylons.response_options``
80
A dict of Content-Type related default settings for new
81
instances of :class:`~pylons.controllers.util.Response`. May
82
contain the values ``content_type``, ``charset`` and
83
``errors``. Overrides the Pylons default values specified by
84
the ``response_defaults`` dict.
86
Mapper object used for Routing. Yes, it is possible to add
87
routes after your application has started running.
92
'pylons.package': None,
93
'pylons.paths': {'root': None,
96
'static_files': None},
97
'pylons.environ_config': dict(session='beaker.session',
98
cache='beaker.cache'),
99
'pylons.app_globals': None,
101
'pylons.request_options': request_defaults.copy(),
102
'pylons.response_options': response_defaults.copy(),
103
'pylons.strict_tmpl_context': True,
104
'pylons.tmpl_context_attach_args': False,
107
def init_app(self, global_conf, app_conf, package=None, paths=None):
108
"""Initialize configuration for the application
111
This *must* be called at least once, as soon as possible
112
to setup all the configuration options.
115
Several options are expected to be set for a Pylons web
116
application. They will be loaded from the global_config
117
which has the main Paste options. If ``debug`` is not
118
enabled as a global config option, the following option
121
* error_to - The email address to send the debug error to
123
The optional config options in this case are:
125
* smtp_server - The SMTP server to use, defaults to
127
* error_log - A logfile to write the error to
128
* error_subject_prefix - The prefix of the error email
130
* from_address - Whom the error email should be from
132
Defaults supplied via the [app:main] section from the Paste
133
config file. ``load_config`` only cares about whether a
134
'prefix' option is set, if so it will update Routes to
135
ensure URL's take that into account.
137
The name of the application package, to be stored in the
140
.. versionchanged:: 1.0
141
``template_engine`` option is no longer supported.
144
log.debug("Initializing configuration, package: '%s'", package)
145
conf = global_conf.copy()
146
conf.update(app_conf)
147
conf.update(dict(app_conf=app_conf, global_conf=global_conf))
148
conf.update(self.pop('environment_load', {}))
151
conf['pylons.paths'] = paths
152
conf['pylons.package'] = package
154
conf['debug'] = asbool(conf.get('debug'))
156
# Load the MIMETypes with its default types
159
# Ensure all the keys from defaults are present, load them if not
160
for key, val in copy.deepcopy(PylonsConfig.defaults).iteritems():
161
conf.setdefault(key, val)
163
# Load the errorware configuration from the Paste configuration file
164
# These all have defaults, and emails are only sent if configured and
165
# if this application is running in production mode
167
errorware['debug'] = conf['debug']
168
if not errorware['debug']:
169
errorware['debug'] = False
170
errorware['error_email'] = conf.get('email_to')
171
errorware['error_log'] = conf.get('error_log', None)
172
errorware['smtp_server'] = conf.get('smtp_server',
174
errorware['error_subject_prefix'] = conf.get(
175
'error_subject_prefix', 'WebApp Error: ')
176
errorware['from_address'] = conf.get(
177
'from_address', conf.get('error_email_from',
178
'pylons@yourapp.com'))
179
errorware['error_message'] = conf.get('error_message',
180
'An internal server error occurred')
182
# Copy in some defaults
183
if 'cache_dir' in conf:
184
conf.setdefault('beaker.session.data_dir',
185
os.path.join(conf['cache_dir'], 'sessions'))
186
conf.setdefault('beaker.cache.data_dir',
187
os.path.join(conf['cache_dir'], 'cache'))
189
conf['pylons.cache_dir'] = conf.pop('cache_dir',
190
conf['app_conf'].get('cache_dir'))
191
# Save our errorware values
192
conf['pylons.errorware'] = errorware
194
# Load conf dict into self
198
pylons_config = PylonsConfig()
201
# Push an empty config so all accesses to config at import time have something
202
# to look at and modify. This config will be merged with the app's when it's
203
# built in the paste.app_factory entry point.
204
pylons_config.update(copy.deepcopy(PylonsConfig.defaults))
205
config.push_process_config(pylons_config)