pylons.configuration
Covered: 44 lines
Missed: 112 lines
Skipped 50 lines
Percent: 28 %
  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
  7
conflicts.
  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
 13
and Routes.
 15
"""
 16
import copy
 17
import logging
 18
import os
 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
 55
    be interested in:
 57
    ``pylons.paths``
 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
 72
        controllers method.
 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.
 85
    ``routes.map``
 86
        Mapper object used for Routing. Yes, it is possible to add
 87
        routes after your application has started running.
 89
    """
 90
    defaults = {
 91
        'debug': False,
 92
        'pylons.package': None,
 93
        'pylons.paths': {'root': None,
 94
                         'controllers': None,
 95
                         'templates': [],
 96
                         'static_files': None},
 97
        'pylons.environ_config': dict(session='beaker.session', 
 98
                                      cache='beaker.cache'),
 99
        'pylons.app_globals': None,
100
        'pylons.h': 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,
105
    }
107
    def init_app(self, global_conf, app_conf, package=None, paths=None):
108
        """Initialize configuration for the application
110
        .. note
111
            This *must* be called at least once, as soon as possible 
112
            to setup all the configuration options.
114
        ``global_conf``
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
119
            *must* be set:
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 
126
              'localhost'
127
            * error_log - A logfile to write the error to
128
            * error_subject_prefix - The prefix of the error email
129
              subject
130
            * from_address - Whom the error email should be from
131
        ``app_conf``
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.
136
        ``package``
137
            The name of the application package, to be stored in the 
138
            app_conf.
140
        .. versionchanged:: 1.0
141
            ``template_engine`` option is no longer supported.
143
        """
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', {}))
150
        if paths:
151
            conf['pylons.paths'] = paths
152
        conf['pylons.package'] = package
154
        conf['debug'] = asbool(conf.get('debug'))
157
        MIMETypes.init()
160
        for key, val in copy.deepcopy(PylonsConfig.defaults).iteritems():
161
            conf.setdefault(key, val)
166
        errorware = {}
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',
173
                'localhost')
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')
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'))
192
        conf['pylons.errorware'] = errorware
195
        self.update(conf)
198
pylons_config = PylonsConfig()
204
pylons_config.update(copy.deepcopy(PylonsConfig.defaults))
205
config.push_process_config(pylons_config)