Configuration In Paste
======================

:author: Ian Bicking <ianb@colorstudy.com>
:revision: $Rev$
:date: $LastChangedDate$

.. contents::

Introduction
------------

This document covers Paste configuration; both how to use the
configuration from your application, and how to configure Paste
applications.

Configuration Format
--------------------

Configuration files are Python syntax.  That means any Python
expression can go in the files, and of course that they must be valid
Python.  

By default Paste will look for a configuration file named
``server.conf``, though you can specify a different (or additional)
configuration file with the ``-f`` option to ``paster``.

All global variables in a configuration file are put into the
configuration.  So a configuration file just looks like::

    connection_string = 'dbname=foo'
    server = 'wsgiutils'
    port = 5000
    publish_object = 'myapp:app'
    framework = 'fancy_framework'

This configuration will be given to nearly all parts of the system,
and those parts will pick out variables that are of interest to them.
For example ``server = 'wsgiutils'`` is used by ``paster serve`` to
pick a server.  ``framework = 'fancy_framework'`` is used to build
your WSGI application from the configuration file.
``connection_string = 'dbname=foo'`` is, presumably, used by your
application to open a database connection.

Command-line Options
--------------------

The ``paster serve`` command also takes arbitrary command-line options,
and turns them into configuration values.  So
``--connection-string=dbname=foo`` will add or overwrite the
configuration value.

If the application or component cannot accept strings for a
configuration value, this will not work.  Most components included
with Paste accept strings.  Note that the empty string is false (e.g.,
``--do-something=``) and a non-empty string is true (e.g.,
``--do-something=t``).  ``--do-something=f`` is **true** (since all
non-empty strings are true in Python).

Other ``paster`` commands do not take arbitrary configuration values
like this.

Including and Nesting Configuration
-----------------------------------

Several configuration files can be loaded, and configuration files can
include other configuration files.  Two commands in particular are
important for this::

    include('filename.conf')
    options = load('filename.conf')

``include(filename)`` loads the given file, and uses all its
configuration values.  ``load(filename)`` loads the file, but
*returns* all its configuration values -- this is for nested
configuration.  So in this example ``options`` would be a dictionary
of configuration values.  In most cases you'll use ``include()``.

When a configuration file is being evaluated, it also has access to
all the values already loaded.  So you can do::

    index_files = ['index', 'main']
    include('other_file.conf')

And in ``other_file.conf``::

    index_files.append('default')

This kind of flexibility is very useful, and gives
sub-configuration-files the ability to augment or replace previous
values.  You can also use any other Python commands you like,
including things like::

    js_url = '/js-lib'
    calendar_url = js_url + '/calendar'

One useful thing is to have "profiles".  So you would start your
server like::

    $ paster serve --profile=devel

And in your configuration::

    value1 = ...
    (and other defaults)
    include(profile + '.conf')

This is a good way for overriding configuration for development and
production environments.

Accessing Configuration
-----------------------

When in a request, the object ``environ['paste.config']`` will give
you the configuration.  This object is a dictionary-like object.  You
can change values, and load more configuration files with
``conf.load(filename)``.  For instance, you could use this to load
additional configuration for different requests.  The configuration is
copied for every request, so modifications to the configuration do not
effect future or concurrent requests.  As an example, if you are using
``urlparser.URLParser`` you could put this in your ``__init__.py``::

    def urlparser_hook(environ):
        environ['paste.config'].load(
            os.path.join(os.path.dirname(__file__), 'dir.conf'))

Frameworks are free to make this variable available through more
convenient means.

Often, though, you'll find you need a configuration value in some
routine, and the request or the configuration was not passed in.  In
these cases you can use ``paste.CONFIG``, which acts like a dictionary
and represents the current configuration (for this request or
process).

``paste.CONFIG`` is a global object that can have configuration
*registered*.  You do this like::

    from paste import CONFIG
    from paste.pyconfig import Config
    conf = Config()
    conf.load('file.conf')
    CONFIG.push_process_config(conf)

You can also use ``CONFIG.push_thread_config(conf)`` to just set the
configuration for the current thread.  During a web request this is
done for you, so you can safely use ``paste.CONFIG`` to access the
configuration.  If you are using the same configuration for other
means, like a background process, you can use ``push_process_config``
to load the configuration manually.  Also, the "main"
(``server.conf``) configuration is loaded as the process configuration
when using ``paster serve``.

More Information
----------------

For more details of the configuration object and its use, see the
`reference documentation
<http://pythonpaste.org/docs/reference.html#module-paste-pyconfig>`_.
