Most people already understand “configuration” as settings that influence the
operation of an application. For instance, it’s easy to think of the values
.ini file parsed at application startup time as “configuration”.
However, if you’re reasonably open-minded, it’s easy to think of code as
configuration too. Since Pyramid, like most other web application platforms,
is a framework, it calls into code that you write (as opposed to a
library, which is code that exists purely for you to call). The act of
plugging application code that you’ve written into Pyramid is also
referred to within this documentation as “configuration”; you are configuring
Pyramid to call the code that makes up your application.
“Imperative configuration” just means configuration done by Python statements, one after the next. Here’s one of the simplest Pyramid applications, configured imperatively:
1 2 3 4 5 6 7 8 9 10 11 12
from paste.httpserver import serve from pyramid.config import Configurator from pyramid.response import Response def hello_world(request): return Response('Hello world!') if __name__ == '__main__': config = Configurator() config.add_view(hello_world) app = config.make_wsgi_app() serve(app, host='0.0.0.0')
We won’t talk much about what this application does yet. Just note that the
“configuration’ statements take place underneath the
if __name__ ==
'__main__': stanza in the form of method calls on a Configurator
config.add_view(...)). These statements take place one
after the other, and are executed in order, so the full power of Python,
including conditionals, can be employed in this mode of configuration.
It’s sometimes painful to have all configuration done by imperative code, because often the code for a single application may live in many files. If the configuration is centralized in one place, you’ll need to have at least two files open at once to see the “big picture”: the file that represents the configuration, and the file that contains the implementation objects referenced by the configuration. To avoid this, Pyramid allows you to insert configuration decoration statements very close to code that is referred to by the declaration itself. For example:
1 2 3 4 5 6
from pyramid.response import Response from pyramid.view import view_config @view_config(name='hello', request_method='GET') def hello(request): return Response('Hello')
The mere existence of configuration decoration doesn’t cause any configuration registration to be performed. Before it has any effect on the configuration of a Pyramid application, a configuration decoration within application code must be found through a process known as a scan.
A scan of a module or a package and its subpackages
for decorations happens when the
method is invoked: scanning implies searching for configuration declarations
in a package and its subpackages. For example:
Starting A Scan
1 2 3 4 5 6 7 8 9 10 11 12 13 14
from paste.httpserver import serve from pyramid.response import Response from pyramid.view import view_config @view_config() def hello(request): return Response('Hello') if __name__ == '__main__': from pyramid.config import Configurator config = Configurator() config.scan() app = config.make_wsgi_app() serve(app, host='0.0.0.0')
The scanning machinery imports each module and subpackage in a package or
module recursively, looking for special attributes attached to objects
defined within a module. These special attributes are typically attached to
code via the use of a decorator. For example, the
view_config decorator can be attached to a function or
Once scanning is invoked, and configuration decoration is found by the scanner, a set of calls are made to a Configurator on your behalf: these calls replace the need to add imperative configuration statements that don’t live near the code being configured.
There are two ways to configure a Pyramid application: declaratively and imperatively. You can choose the mode you’re most comfortable with; both are completely equivalent. Examples in this documentation will use both modes interchangeably.