Chris McDonough
2010-12-19 97d7195cfd6f7022b7515df180c97180855fe217
fix urldispatch chapter
1 files modified
805 ■■■■ changed files
docs/narr/urldispatch.rst 805 ●●●● patch | view | raw | blame | history
docs/narr/urldispatch.rst
@@ -33,9 +33,8 @@
easier to use than traversal, and is often a more natural fit for creating an
application that manipulates "flat" data.
The presence of calls to the
:meth:`pyramid.config.Configurator.add_route` method in imperative
configuration within your application is a sign that you're using :term:`URL
The presence of calls to the :meth:`pyramid.config.Configurator.add_route`
method within your application is a sign that you're using :term:`URL
dispatch`.
.. note::
@@ -51,8 +50,8 @@
matching patterns present in a *route map*.
If any route pattern matches the information in the :term:`request` provided
to :app:`Pyramid`, a route-specific :term:`context` resource and :term:`view
name` will be generated.  In this circumstance, :app:`Pyramid` will shortcut
to :app:`Pyramid`, a route-specific :term:`context` resource will be
generated.  When this happens, :app:`Pyramid` will shortcut
:term:`traversal`, and will invoke :term:`view lookup` using the context
resource and view name generated by URL dispatch.  If the matched route names
a :term:`view callable` in its configuration, that view callable will be
@@ -65,13 +64,13 @@
Route Configuration
-------------------
:term:`Route configuration` is the act of adding a new :term:`route`
to an application.  A route has a *pattern*, representing a pattern
meant to match against the ``PATH_INFO`` portion of a URL, and a
*name*, which is used by developers within a :app:`Pyramid`
application to uniquely identify a particular route when generating a
URL.  It also optionally has a ``factory``, a set of :term:`route
predicate` parameters, and a set of :term:`view` parameters.
:term:`Route configuration` is the act of adding a new :term:`route` to an
application.  A route has a *pattern*, representing a pattern meant to match
against the ``PATH_INFO`` portion of a URL, and a *name*, which is used by
developers within a :app:`Pyramid` application to uniquely identify a
particular route when generating a URL.  It also optionally has a
``factory``, a set of :term:`route predicate` parameters, and a set of
:term:`view` parameters.
.. index::
   single: add_route
@@ -79,9 +78,9 @@
Configuring a Route via The ``add_route`` Configurator Method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The :meth:`pyramid.config.Configurator.add_route` method
adds a single :term:`route configuration` to the :term:`application
registry`.  Here's an example:
The :meth:`pyramid.config.Configurator.add_route` method adds a single
:term:`route configuration` to the :term:`application registry`.  Here's an
example:
.. ignore-next-block
.. code-block:: python
@@ -103,12 +102,11 @@
Route Configuration That Names a View Callable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a route configuration declaration names a ``view`` attribute, the
value of the attribute will reference a :term:`view callable`.  A view
callable, as described in :ref:`views_chapter`, is developer-supplied
code that "does stuff" as the result of a request.  For more
information about how to create view callables, see
:ref:`views_chapter`.
When a route configuration declaration names a ``view`` attribute, the value
of the attribute will reference a :term:`view callable`.  A view callable, as
described in :ref:`views_chapter`, is developer-supplied code that "does
stuff" as the result of a request.  For more information about how to create
view callables, see :ref:`views_chapter`.
Here's an example route configuration that references a view callable:
@@ -135,53 +133,51 @@
                    view='myproject.views.myview')
When a route configuration names a ``view`` attribute, the :term:`view
callable` named as that ``view`` attribute will always be found and
invoked when the associated route pattern matches during a request.
callable` named as that ``view`` attribute will always be found and invoked
when the associated route pattern matches during a request.
The purpose of making it possible to specify a view callable within a route
configuration is to prevent developers from needing to deeply understand the
details of :term:`resource location` and :term:`view lookup`.  When a route
names a view callable, and a request enters the system which matches the
pattern of the route, the result is simple: the view callable associated with
the route is invoked with the request that caused the invocation.
names a view callable as a ``view`` argument, and a request enters the system
which matches the pattern of the route, the result is simple: the view
callable associated with the route is invoked with the request that caused
the invocation.
For most usage, you needn't understand more than this; how it works is
an implementation detail.  In the interest of completeness, however,
we'll explain how it *does* work in the following section.  You can
skip it if you're uninterested.
For most usage, you needn't understand more than this; how it works is an
implementation detail.  In the interest of completeness, however, we'll
explain how it *does* work in the following section.  You can skip it if
you're uninterested.
Route View Callable Registration and Lookup Details
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
When a ``view`` attribute is attached to a route configuration,
:app:`Pyramid` ensures that a :term:`view configuration` is
registered that will always be found when the route pattern is matched
during a request.  To do so:
:app:`Pyramid` ensures that a :term:`view configuration` is registered that
will always be found when the route pattern is matched during a request.  To
do so:
- A special route-specific :term:`interface` is created at startup time
  for each route configuration declaration.
- A special route-specific :term:`interface` is created at startup time for
  each route configuration declaration.
- When a route configuration declaration mentions a ``view``
  attribute, a :term:`view configuration` is registered at startup
  time.  This view configuration uses the route-specific interface as
  a :term:`request` type.
- When a route configuration declaration mentions a ``view`` attribute, a
  :term:`view configuration` is registered at startup time.  This view
  configuration uses the route-specific interface as a :term:`request` type.
- At runtime, when a request causes any route to match, the
  :term:`request` object is decorated with the route-specific
  interface.
- At runtime, when a request causes any route to match, the :term:`request`
  object is decorated with the route-specific interface.
- The fact that the request is decorated with a route-specific
  interface causes the view lookup machinery to always use the view
  callable registered using that interface by the route configuration
  to service requests that match the route pattern.
- The fact that the request is decorated with a route-specific interface
  causes the view lookup machinery to always use the view callable registered
  using that interface by the route configuration to service requests that
  match the route pattern.
In this way, we supply a shortcut to the developer.  Under the hood,
the :term:`resource location` and :term:`view lookup` subsystems
provided by :app:`Pyramid` are still being utilized, but in a way
which does not require a developer to understand either of them in
detail.  It also means that we can allow a developer to combine
:term:`URL dispatch` and :term:`traversal` in various exceptional
cases as documented in :ref:`hybrid_chapter`.
In this way, we supply a shortcut to the developer.  Under the hood, the
:term:`resource location` and :term:`view lookup` subsystems provided by
:app:`Pyramid` are still being utilized, but in a way which does not require
a developer to understand either of them in detail.  It also means that we
can allow a developer to combine :term:`URL dispatch` and :term:`traversal`
in various exceptional cases as documented in :ref:`hybrid_chapter`.
.. index::
   single: route path pattern syntax
@@ -191,14 +187,14 @@
Route Pattern Syntax
~~~~~~~~~~~~~~~~~~~~
The syntax of the pattern matching language used by :app:`Pyramid`
URL dispatch in the *pattern* argument is straightforward; it is close
to that of the :term:`Routes` system used by :term:`Pylons`.
The syntax of the pattern matching language used by :app:`Pyramid` URL
dispatch in the *pattern* argument is straightforward; it is close to that of
the :term:`Routes` system used by :term:`Pylons`.
The *pattern* used in route configuration may start with a slash
character.  If the pattern does not start with a slash character, an
implicit slash will be prepended to it at matching time.  For example,
the following patterns are equivalent:
The *pattern* used in route configuration may start with a slash character.
If the pattern does not start with a slash character, an implicit slash will
be prepended to it at matching time.  For example, the following patterns are
equivalent:
.. code-block:: text
@@ -210,23 +206,22 @@
   /{foo}/bar/baz
A pattern segment (an individual item between ``/`` characters in the pattern)
may either be a literal string (e.g. ``foo``) *or* it may be a replacement
marker (e.g. ``{foo}``) or a certain combination of both. A replacement marker
does not need to be preceded by a ``/`` character.
A pattern segment (an individual item between ``/`` characters in the
pattern) may either be a literal string (e.g. ``foo``) *or* it may be a
replacement marker (e.g. ``{foo}``) or a certain combination of both. A
replacement marker does not need to be preceded by a ``/`` character.
A replacement marker is in the format ``{name}``, where this
means "accept any characters up to the next non-alphanumeric character
and use this as the ``name`` matchdict value."  For example, the
following pattern defines one literal segment ("foo") and two dynamic
replacement markers ("baz", and "bar"):
A replacement marker is in the format ``{name}``, where this means "accept
any characters up to the next non-alphanumeric character and use this as the
``name`` matchdict value."  For example, the following pattern defines one
literal segment ("foo") and two dynamic replacement markers ("baz", and
"bar"):
.. code-block:: text
   foo/{baz}/{bar}
The above pattern will match these URLs, generating the following
matchdicts:
The above pattern will match these URLs, generating the following matchdicts:
.. code-block:: text
@@ -240,19 +235,19 @@
   foo/1/2/        -> No match (trailing slash)
   bar/abc/def     -> First segment literal mismatch
The match for a segment replacement marker in a segment will be done
only up to the first non-alphanumeric character in the segment in the
pattern.  So, for instance, if this route pattern was used:
The match for a segment replacement marker in a segment will be done only up
to the first non-alphanumeric character in the segment in the pattern.  So,
for instance, if this route pattern was used:
.. code-block:: text
   foo/{name}.html
The literal path ``/foo/biz.html`` will match the above route pattern,
and the match result will be ``{'name':u'biz'}``.  However, the
literal path ``/foo/biz`` will not match, because it does not contain
a literal ``.html`` at the end of the segment represented by
``{name}.html`` (it only contains ``biz``, not ``biz.html``).
The literal path ``/foo/biz.html`` will match the above route pattern, and
the match result will be ``{'name':u'biz'}``.  However, the literal path
``/foo/biz`` will not match, because it does not contain a literal ``.html``
at the end of the segment represented by ``{name}.html`` (it only contains
``biz``, not ``biz.html``).
To capture both segments, two replacement markers can be used:
@@ -260,27 +255,26 @@
    
    foo/{name}.{ext}
The literal path ``/foo/biz.html`` will match the above route pattern,
and the match result will be ``{'name': 'biz', 'ext': 'html'}``. This
occurs because the replacement marker ``{name}`` has a literal part of
``.`` (period) between the other replacement marker ``{ext}``.
The literal path ``/foo/biz.html`` will match the above route pattern, and
the match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs
because the replacement marker ``{name}`` has a literal part of ``.``
(period) between the other replacement marker ``{ext}``.
It is possible to use two replacement markers without any literal
characters between them, for instance ``/{foo}{bar}``. However, this
would be a nonsensical pattern without specifying a custom regular
expression to restrict what each marker captures.
It is possible to use two replacement markers without any literal characters
between them, for instance ``/{foo}{bar}``. However, this would be a
nonsensical pattern without specifying a custom regular expression to
restrict what each marker captures.
Segments must contain at least one character in order to match a
segment replacement marker.  For example, for the URL ``/abc/``:
Segments must contain at least one character in order to match a segment
replacement marker.  For example, for the URL ``/abc/``:
- ``/abc/{foo}`` will not match.
- ``/{foo}/`` will match.
Note that values representing path segments matched with a
``{segment}`` match will be url-unquoted and decoded from UTF-8 into
Unicode within the matchdict.  So for instance, the following
pattern:
Note that values representing path segments matched with a ``{segment}``
match will be url-unquoted and decoded from UTF-8 into Unicode within the
matchdict.  So for instance, the following pattern:
.. code-block:: text
@@ -292,35 +286,32 @@
   foo/La%20Pe%C3%B1a
The matchdict will look like so (the value is URL-decoded / UTF-8
decoded):
The matchdict will look like so (the value is URL-decoded / UTF-8 decoded):
.. code-block:: text
   {'bar':u'La Pe\xf1a'}
If the pattern has a ``*`` in it, the name which follows it is
considered a "remainder match".  A remainder match *must* come at the
end of the pattern.  Unlike segment replacement markers, it does not
need to be preceded by a slash.  For example:
If the pattern has a ``*`` in it, the name which follows it is considered a
"remainder match".  A remainder match *must* come at the end of the pattern.
Unlike segment replacement markers, it does not need to be preceded by a
slash.  For example:
.. code-block:: text
   foo/{baz}/{bar}*fizzle
The above pattern will match these URLs, generating the following
matchdicts:
The above pattern will match these URLs, generating the following matchdicts:
.. code-block:: text
   foo/1/2/           -> {'baz':'1', 'bar':'2', 'fizzle':()}
   foo/abc/def/a/b/c  -> {'baz':'abc', 'bar':'def', 'fizzle':('a', 'b', 'c')}
Note that when a ``*stararg`` remainder match is matched, the value
put into the matchdict is turned into a tuple of path segments
representing the remainder of the path.  These path segments are
url-unquoted and decoded from UTF-8 into Unicode.  For example, for
the following pattern:
Note that when a ``*stararg`` remainder match is matched, the value put into
the matchdict is turned into a tuple of path segments representing the
remainder of the path.  These path segments are url-unquoted and decoded from
UTF-8 into Unicode.  For example, for the following pattern:
.. code-block:: text
@@ -346,8 +337,7 @@
    
    foo/{baz}/{bar}{fizzle:.*}
The above pattern will match these URLs, generating the following
matchdicts:
The above pattern will match these URLs, generating the following matchdicts:
.. code-block:: text
@@ -356,8 +346,8 @@
This occurs because the default regular expression for a marker is ``[^/]+``
which will match everything up to the first ``/``, while ``{fizzle:.*}`` will
result in a regular expression match of ``.*`` capturing the remainder into
a single value.
result in a regular expression match of ``.*`` capturing the remainder into a
single value.
.. index::
   single: route ordering
@@ -365,18 +355,18 @@
Route Declaration Ordering
~~~~~~~~~~~~~~~~~~~~~~~~~~
Route configuration declarations are evaluated in a specific
order when a request enters the system. As a result, the
order of route configuration declarations is very important.
Route configuration declarations are evaluated in a specific order when a
request enters the system. As a result, the order of route configuration
declarations is very important.
The order that routes declarations are evaluated is the order in which
they are added to the application at startup time.  This is unlike
:term:`traversal`, which depends on emergent behavior which happens as
a result of traversing a resource tree.
The order that routes declarations are evaluated is the order in which they
are added to the application at startup time.  This is unlike
:term:`traversal`, which depends on emergent behavior which happens as a
result of traversing a resource tree.
For routes added via the :mod:`pyramid.config.Configurator.add_route`
method, the order that routes are evaluated is the order in which they are
added to the configuration imperatively.
For routes added via the :mod:`pyramid.config.Configurator.add_route` method,
the order that routes are evaluated is the order in which they are added to
the configuration imperatively.
For example, route configuration statements with the following patterns might
be added in the following order:
@@ -388,8 +378,8 @@
In such a configuration, the ``members/abc`` pattern would *never* be
matched. This is because the match ordering will always match
``members/{def}`` first; the route configuration with ``members/abc``
will never be evaluated.
``members/{def}`` first; the route configuration with ``members/abc`` will
never be evaluated.
.. index::
   single: route factory
@@ -419,7 +409,7 @@
supply a different :term:`context` resource object to the view related to
each particular route.
Supplying a different context resource for each route is useful when you're
Supplying a different resource factory each route is useful when you're
trying to use a :app:`Pyramid` :term:`authorization policy` to provide
declarative, "context sensitive" security checks; each resource can maintain
a separate :term:`ACL`, as documented in
@@ -433,30 +423,29 @@
Route configuration ``add_route`` statements may specify a large number of
arguments.
Many of these arguments are :term:`route predicate` arguments.  A
route predicate argument specifies that some aspect of the request
must be true for the associated route to be considered a match during
the route matching process.
Many of these arguments are :term:`route predicate` arguments.  A route
predicate argument specifies that some aspect of the request must be true for
the associated route to be considered a match during the route matching
process.
Other arguments are view configuration related arguments.  These only
have an effect when the route configuration names a ``view``.
Other arguments are view configuration related arguments.  These only have an
effect when the route configuration names a ``view``.
Other arguments are ``name`` and ``factory``.  These arguments
represent neither predicates nor view configuration information.
Other arguments are ``name`` and ``factory``.  These arguments represent
neither predicates nor view configuration information.
**Non-Predicate Arguments**
``name``
  The name of the route, e.g. ``myroute``.  This attribute is
  required.  It must be unique among all defined routes in a given
  application.
  The name of the route, e.g. ``myroute``.  This attribute is required.  It
  must be unique among all defined routes in a given application.
``factory``
  A Python object (often a function or a class) or a :term:`dotted
  Python name` to such an object that will generate a
  :app:`Pyramid` :term:`context` resource object when this route
  matches. For example, ``mypackage.resources.MyFactoryClass``.  If this
  argument is not specified, the traversal root factory will be used.
  A Python object (often a function or a class) or a :term:`dotted Python
  name` to such an object that will generate a :app:`Pyramid` resource object
  as the :term:`root` when this route matches. For example,
  ``mypackage.resources.MyFactoryClass``.  If this argument is not specified,
  the traversal root factory will be used.
``traverse``
  If you would like to cause the :term:`context` resource to be something
@@ -477,28 +466,28 @@
  become the :term:`context` resource of the request.
  :ref:`traversal_chapter` has more information about traversal.
  If the traversal path contains segment marker names which are not
  present in the ``pattern`` argument, a runtime error will occur.
  The ``traverse`` pattern should not contain segment markers that do
  not exist in the ``pattern``.
  If the traversal path contains segment marker names which are not present
  in the ``pattern`` argument, a runtime error will occur.  The ``traverse``
  pattern should not contain segment markers that do not exist in the
  ``pattern``.
  A similar combining of routing and traversal is available when a
  route is matched which contains a ``*traverse`` remainder marker in
  its pattern (see :ref:`using_traverse_in_a_route_pattern`).  The
  ``traverse`` argument allows you to associate route patterns with an
  arbitrary traversal path without using a a ``*traverse`` remainder
  marker; instead you can use other match information.
  A similar combining of routing and traversal is available when a route is
  matched which contains a ``*traverse`` remainder marker in its pattern (see
  :ref:`using_traverse_in_a_route_pattern`).  The ``traverse`` argument
  allows you to associate route patterns with an arbitrary traversal path
  without using a a ``*traverse`` remainder marker; instead you can use other
  match information.
  Note that the ``traverse`` argument is ignored when attached to a
  route that has a ``*traverse`` remainder marker in its pattern.
  Note that the ``traverse`` argument is ignored when attached to a route
  that has a ``*traverse`` remainder marker in its pattern.
**Predicate Arguments**
``pattern``
  The path of the route e.g. ``ideas/{idea}``.  This argument is
  required.  See :ref:`route_path_pattern_syntax` for information
  about the syntax of route paths.  If the path doesn't match the
  current URL, route matching continues.
  The path of the route e.g. ``ideas/{idea}``.  This argument is required.
  See :ref:`route_path_pattern_syntax` for information about the syntax of
  route paths.  If the path doesn't match the current URL, route matching
  continues.
  .. note:: In earlier releases of this framework, this argument existed
     as ``path``.  ``path`` continues to work as an alias for
@@ -507,135 +496,123 @@
``xhr``
  This value should be either ``True`` or ``False``.  If this value is
  specified and is ``True``, the :term:`request` must possess an
  ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header for this
  route to match.  This is useful for detecting AJAX requests issued
  from jQuery, Prototype and other Javascript libraries.  If this
  predicate returns ``False``, route matching continues.
  ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header for this route
  to match.  This is useful for detecting AJAX requests issued from jQuery,
  Prototype and other Javascript libraries.  If this predicate returns
  ``False``, route matching continues.
``request_method``
  A string representing an HTTP method name, e.g. ``GET``, ``POST``,
  ``HEAD``, ``DELETE``, ``PUT``.  If this argument is not specified,
  this route will match if the request has *any* request method.  If
  this predicate returns ``False``, route matching continues.
  ``HEAD``, ``DELETE``, ``PUT``.  If this argument is not specified, this
  route will match if the request has *any* request method.  If this
  predicate returns ``False``, route matching continues.
``path_info``
  This value represents a regular expression pattern that will be
  tested against the ``PATH_INFO`` WSGI environment variable.  If the
  regex matches, this predicate will return ``True``.  If this
  predicate returns ``False``, route matching continues.
  This value represents a regular expression pattern that will be tested
  against the ``PATH_INFO`` WSGI environment variable.  If the regex matches,
  this predicate will return ``True``.  If this predicate returns ``False``,
  route matching continues.
``request_param``
  This value can be any string.  A view declaration with this argument
  ensures that the associated route will only match when the request
  has a key in the ``request.params`` dictionary (an HTTP ``GET`` or
  ``POST`` variable) that has a name which matches the supplied value.
  If the value supplied as the argument has a ``=`` sign in it,
  e.g. ``request_params="foo=123"``, then the key (``foo``) must both
  exist in the ``request.params`` dictionary, and the value must match
  the right hand side of the expression (``123``) for the route to
  "match" the current request.  If this predicate returns ``False``,
  route matching continues.
  ensures that the associated route will only match when the request has a
  key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST``
  variable) that has a name which matches the supplied value.  If the value
  supplied as the argument has a ``=`` sign in it,
  e.g. ``request_params="foo=123"``, then the key (``foo``) must both exist
  in the ``request.params`` dictionary, and the value must match the right
  hand side of the expression (``123``) for the route to "match" the current
  request.  If this predicate returns ``False``, route matching continues.
``header``
  This argument represents an HTTP header name or a header name/value
  pair.  If the argument contains a ``:`` (colon), it will be
  considered a name/value pair (e.g. ``User-Agent:Mozilla/.*`` or
  ``Host:localhost``).  If the value contains a colon, the value
  portion should be a regular expression.  If the value does not
  contain a colon, the entire value will be considered to be the
  header name (e.g. ``If-Modified-Since``).  If the value evaluates to
  a header name only without a value, the header specified by the name
  must be present in the request for this predicate to be true.  If
  the value evaluates to a header name/value pair, the header
  specified by the name must be present in the request *and* the
  regular expression specified as the value must match the header
  value.  Whether or not the value represents a header name or a
  header name/value pair, the case of the header name is not
  significant.  If this predicate returns ``False``, route matching
  continues.
  This argument represents an HTTP header name or a header name/value pair.
  If the argument contains a ``:`` (colon), it will be considered a
  name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``).  If
  the value contains a colon, the value portion should be a regular
  expression.  If the value does not contain a colon, the entire value will
  be considered to be the header name (e.g. ``If-Modified-Since``).  If the
  value evaluates to a header name only without a value, the header specified
  by the name must be present in the request for this predicate to be true.
  If the value evaluates to a header name/value pair, the header specified by
  the name must be present in the request *and* the regular expression
  specified as the value must match the header value.  Whether or not the
  value represents a header name or a header name/value pair, the case of the
  header name is not significant.  If this predicate returns ``False``, route
  matching continues.
``accept``
  This value represents a match query for one or more mimetypes in the
  ``Accept`` HTTP request header.  If this value is specified, it must
  be in one of the following forms: a mimetype match token in the form
  ``text/plain``, a wildcard mimetype match token in the form
  ``text/*`` or a match-all wildcard mimetype match token in the form
  ``*/*``.  If any of the forms matches the ``Accept`` header of the
  request, this predicate will be true.  If this predicate returns
  ``False``, route matching continues.
  ``Accept`` HTTP request header.  If this value is specified, it must be in
  one of the following forms: a mimetype match token in the form
  ``text/plain``, a wildcard mimetype match token in the form ``text/*`` or a
  match-all wildcard mimetype match token in the form ``*/*``.  If any of the
  forms matches the ``Accept`` header of the request, this predicate will be
  true.  If this predicate returns ``False``, route matching continues.
``custom_predicates``
  This value should be a sequence of references to custom predicate
  callables.  Use custom predicates when no set of predefined
  predicates does what you need.  Custom predicates can be combined
  with predefined predicates as necessary.  Each custom predicate
  callable should accept two arguments: ``context`` and ``request``
  and should return either ``True`` or ``False`` after doing arbitrary
  evaluation of the context resource and/or the request.  If all callables
  return ``True``, the associated route will be considered viable for
  a given request.  If any custom predicate returns ``False``, route
  matching continues.  Note that the value ``context`` will always be
  ``None`` when passed to a custom route predicate.
  callables.  Use custom predicates when no set of predefined predicates does
  what you need.  Custom predicates can be combined with predefined
  predicates as necessary.  Each custom predicate callable should accept two
  arguments: ``context`` and ``request`` and should return either ``True`` or
  ``False`` after doing arbitrary evaluation of the context resource and/or
  the request.  If all callables return ``True``, the associated route will
  be considered viable for a given request.  If any custom predicate returns
  ``False``, route matching continues.  Note that the value ``context`` will
  always be ``None`` when passed to a custom route predicate.
**View-Related Arguments**
``view``
  A Python object or a :term:`dotted Python name` to such an object
  that will be used as a view callable when this route
  A Python object or a :term:`dotted Python name` to such an object that will
  be used as a view callable when this route
  matches. e.g. ``mypackage.views.my_view``.
  
``view_context``
  A class or an :term:`interface` (or a :term:`dotted Python name` to
  such an object) that the :term:`context` of the view should match
  for the view named by the route to be used.  This argument is only
  useful if the ``view`` attribute is used.  If this attribute is not
  specified, the default (``None``) will be used.
  A class or an :term:`interface` (or a :term:`dotted Python name` to such an
  object) that the :term:`context` resource should possess for the view named
  by the route to be used.  If this attribute is not specified, the default
  (``None``) will be used.
  If the ``view`` argument is not provided, this argument has
  no effect.
  If the ``view`` argument is not provided, this argument has no effect.
  This attribute can also be spelled as ``for_`` or ``view_for``.
``view_permission``
  The permission name required to invoke the view associated with this
  route.  e.g. ``edit``. (see :ref:`using_security_with_urldispatch`
  for more information about permissions).
  The permission name required to invoke the view associated with this route.
  e.g. ``edit``. (see :ref:`using_security_with_urldispatch` for more
  information about permissions).
  If the ``view`` attribute is not provided, this argument has
  no effect.
  If the ``view`` attribute is not provided, this argument has no effect.
  This argument can also be spelled as ``permission``.
``view_renderer``
  This is either a single string term (e.g. ``json``) or a string
  implying a path or :term:`asset specification`
  (e.g. ``templates/views.pt``).  If the renderer value is a single
  term (does not contain a dot ``.``), the specified term will be used
  to look up a renderer implementation, and that renderer
  implementation will be used to construct a response from the view
  return value.  If the renderer term contains a dot (``.``), the
  specified term will be treated as a path, and the filename extension
  of the last element in the path will be used to look up the renderer
  implementation, which will be passed the full path.  The renderer
  implementation will be used to construct a response from the view
  return value.  See :ref:`views_which_use_a_renderer` for more
  information.
  This is either a single string term (e.g. ``json``) or a string implying a
  path or :term:`asset specification` (e.g. ``templates/views.pt``).  If the
  renderer value is a single term (does not contain a dot ``.``), the
  specified term will be used to look up a renderer implementation, and that
  renderer implementation will be used to construct a response from the view
  return value.  If the renderer term contains a dot (``.``), the specified
  term will be treated as a path, and the filename extension of the last
  element in the path will be used to look up the renderer implementation,
  which will be passed the full path.  The renderer implementation will be
  used to construct a response from the view return value.  See
  :ref:`views_which_use_a_renderer` for more information.
  If the ``view`` argument is not provided, this argument has
  no effect.
  If the ``view`` argument is not provided, this argument has no effect.
  This argument can also be spelled as ``renderer``.
``view_attr``
  The view machinery defaults to using the ``__call__`` method of the
  view callable (or the function itself, if the view callable is a
  function) to obtain a response dictionary.  The ``attr`` value
  allows you to vary the method attribute used to obtain the response.
  For example, if your view was a class, and the class has a method
  named ``index`` and you wanted to use this method instead of the
  class' ``__call__`` method to return the response, you'd say
  ``attr="index"`` in the view configuration for the view.  This is
  most useful when the view definition is a class.
  The view machinery defaults to using the ``__call__`` method of the view
  callable (or the function itself, if the view callable is a function) to
  obtain a response dictionary.  The ``attr`` value allows you to vary the
  method attribute used to obtain the response.  For example, if your view
  was a class, and the class has a method named ``index`` and you wanted to
  use this method instead of the class' ``__call__`` method to return the
  response, you'd say ``attr="index"`` in the view configuration for the
  view.  This is most useful when the view definition is a class.
  If the ``view`` argument is not provided, this argument has no
  effect.
@@ -651,19 +628,18 @@
~~~~~~~~~~~~~~~~~~~~~~~
Each of the predicate callables fed to the ``custom_predicates`` argument of
:meth:`pyramid.config.Configurator.add_route` must be a callable
accepting two arguments.  The first argument passed to a custom predicate is
a dictionary conventionally named ``info``.  The second argument is the
current :term:`request` object.
:meth:`pyramid.config.Configurator.add_route` must be a callable accepting
two arguments.  The first argument passed to a custom predicate is a
dictionary conventionally named ``info``.  The second argument is the current
:term:`request` object.
The ``info`` dictionary has a number of contained values: ``match`` is
a dictionary: it represents the arguments matched in the URL by the
route.  ``route`` is an object representing the route which was
matched (see :class:`pyramid.interfaces.IRoute` for the API of such
a route object).
The ``info`` dictionary has a number of contained values: ``match`` is a
dictionary: it represents the arguments matched in the URL by the route.
``route`` is an object representing the route which was matched (see
:class:`pyramid.interfaces.IRoute` for the API of such a route object).
``info['match']`` is useful when predicates need access to the route
match.  For example:
``info['match']`` is useful when predicates need access to the route match.
For example:
.. code-block:: python
   :linenos:
@@ -679,17 +655,17 @@
   config.add_route('num', '/{num}', 
                    custom_predicates=(num_one_two_or_three,))
The above ``any_of`` function generates a predicate which ensures that
the match value named ``segment_name`` is in the set of allowable
values represented by ``allowed``.  We use this ``any_of`` function to
generate a predicate function named ``num_one_two_or_three``, which
ensures that the ``num`` segment is one of the values ``one``,
``two``, or ``three`` , and use the result as a custom predicate by
feeding it inside a tuple to the ``custom_predicates`` argument to
The above ``any_of`` function generates a predicate which ensures that the
match value named ``segment_name`` is in the set of allowable values
represented by ``allowed``.  We use this ``any_of`` function to generate a
predicate function named ``num_one_two_or_three``, which ensures that the
``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use
the result as a custom predicate by feeding it inside a tuple to the
``custom_predicates`` argument to
:meth:`pyramid.config.Configurator.add_route`.
A custom route predicate may also *modify* the ``match`` dictionary.
For instance, a predicate might do some type conversion of values:
A custom route predicate may also *modify* the ``match`` dictionary.  For
instance, a predicate might do some type conversion of values:
.. code-block:: python
   :linenos:
@@ -710,10 +686,9 @@
    config.add_route('num', '/{year}/{month}/{day}', 
                     custom_predicates=(ymd_to_int,))
Note that a conversion predicate is still a predicate so it must
return ``True`` or ``False``; a predicate that does *only* conversion,
such as the one we demonstrate above should unconditionally return
``True``.
Note that a conversion predicate is still a predicate so it must return
``True`` or ``False``; a predicate that does *only* conversion, such as the
one we demonstrate above should unconditionally return ``True``.
To avoid the try/except uncertainty, the route pattern can contain regular
expressions specifying requirements for that marker. For instance:
@@ -738,28 +713,27 @@
all unless these markers match ``\d+`` which requires them to be valid digits
for an ``int`` type conversion.
The ``match`` dictionary passed within ``info`` to each predicate
attached to a route will be the same dictionary.  Therefore, when
registering a custom predicate which modifies the ``match`` dict, the
code registering the predicate should usually arrange for the
predicate to be the *last* custom predicate in the custom predicate
list.  Otherwise, custom predicates which fire subsequent to the
predicate which performs the ``match`` modification will receive the
*modified* match dictionary.
The ``match`` dictionary passed within ``info`` to each predicate attached to
a route will be the same dictionary.  Therefore, when registering a custom
predicate which modifies the ``match`` dict, the code registering the
predicate should usually arrange for the predicate to be the *last* custom
predicate in the custom predicate list.  Otherwise, custom predicates which
fire subsequent to the predicate which performs the ``match`` modification
will receive the *modified* match dictionary.
.. warning::
   It is a poor idea to rely on ordering of custom predicates to build
   some conversion pipeline, where one predicate depends on the side
   effect of another.  For instance, it's a poor idea to register two
   custom predicates, one which handles conversion of a value to an
   int, the next which handles conversion of that integer to some
   custom object.  Just do all that in a single custom predicate.
   It is a poor idea to rely on ordering of custom predicates to build a
   conversion pipeline, where one predicate depends on the side effect of
   another.  For instance, it's a poor idea to register two custom
   predicates, one which handles conversion of a value to an int, the next
   which handles conversion of that integer to some custom object.  Just do
   all that in a single custom predicate.
The ``route`` object in the ``info`` dict is an object that has two
useful attributes: ``name`` and ``pattern``.  The ``name`` attribute
is the route name.  The ``pattern`` attribute is the route pattern.
An example of using the route in a set of route predicates:
The ``route`` object in the ``info`` dict is an object that has two useful
attributes: ``name`` and ``pattern``.  The ``name`` attribute is the route
name.  The ``pattern`` attribute is the route pattern.  An example of using
the route in a set of route predicates:
.. code-block:: python
   :linenos:
@@ -773,42 +747,39 @@
    config.add_route('ymd', '/{year}/{month}/{day}', 
                     custom_predicates=(twenty_ten,))
The above predicate, when added to a number of route configurations
ensures that the year match argument is '2010' if and only if the
route name is 'ymd', 'ym', or 'y'.
The above predicate, when added to a number of route configurations ensures
that the year match argument is '2010' if and only if the route name is
'ymd', 'ym', or 'y'.
See also :class:`pyramid.interfaces.IRoute` for more API
documentation about a route object.
See also :class:`pyramid.interfaces.IRoute` for more API documentation about
route objects.
Route Matching
--------------
The main purpose of route configuration is to match (or not match)
the ``PATH_INFO`` present in the WSGI environment provided during a
request against a URL path pattern.
The main purpose of route configuration is to match (or not match) the
``PATH_INFO`` present in the WSGI environment provided during a request
against a URL path pattern.
The way that :app:`Pyramid` does this is very simple.  When a
request enters the system, for each route configuration declaration
present in the system, :app:`Pyramid` checks the ``PATH_INFO``
against the pattern declared.
The way that :app:`Pyramid` does this is very simple.  When a request enters
the system, for each route configuration declaration present in the system,
:app:`Pyramid` checks the ``PATH_INFO`` against the pattern declared.
If any route matches, the route matching process stops.  The :term:`request`
is decorated with a special :term:`interface` which describes it as a "route
request", the :term:`context` resource is generated, and the context, the
view name, and the resulting request are handed off to :term:`view lookup`.
This process is otherwise known as :term:`resource location`.  During view
lookup, if any ``view`` argument was provided within the matched route
configuration, the :term:`view callable` it points to is called.
request", the :term:`context` resource is generated, and the context and the
resulting request are handed off to :term:`view lookup`.  During view lookup,
if any ``view`` argument was provided within the matched route configuration,
the :term:`view callable` it points to is called.
When a route configuration is declared, it may contain :term:`route
predicate` arguments.  All route predicates associated with a route
declaration must be ``True`` for the route configuration to be used
for a given request.
declaration must be ``True`` for the route configuration to be used for a
given request.
If any predicate in the set of :term:`route predicate` arguments
provided to a route configuration returns ``False``, that route is
skipped and route matching continues through the ordered set of
routes.
If any predicate in the set of :term:`route predicate` arguments provided to
a route configuration returns ``False``, that route is skipped and route
matching continues through the ordered set of routes.
If no route matches after all route patterns are exhausted, :app:`Pyramid`
falls back to :term:`traversal` to do :term:`resource location` and
@@ -822,12 +793,12 @@
The Matchdict
~~~~~~~~~~~~~
When the URL pattern associated with a particular route configuration
is matched by a request, a dictionary named ``matchdict`` is added as
an attribute of the :term:`request` object.  Thus,
``request.matchdict`` will contain the values that match replacement
patterns in the ``pattern`` element.  The keys in a matchdict will be
strings.  The values will be Unicode objects.
When the URL pattern associated with a particular route configuration is
matched by a request, a dictionary named ``matchdict`` is added as an
attribute of the :term:`request` object.  Thus, ``request.matchdict`` will
contain the values that match replacement patterns in the ``pattern``
element.  The keys in a matchdict will be strings.  The values will be
Unicode objects.
.. note::
@@ -842,13 +813,12 @@
The Matched Route
~~~~~~~~~~~~~~~~~
When the URL pattern associated with a particular route configuration
is matched by a request, an object named ``matched_route`` is added as
an attribute of the :term:`request` object.  Thus,
``request.matched_route`` will be an object implementing the
:class:`pyramid.interfaces.IRoute` interface which matched the
request.  The most useful attribute of the route object is ``name``,
which is the name of the route that matched.
When the URL pattern associated with a particular route configuration is
matched by a request, an object named ``matched_route`` is added as an
attribute of the :term:`request` object.  Thus, ``request.matched_route``
will be an object implementing the :class:`pyramid.interfaces.IRoute`
interface which matched the request.  The most useful attribute of the route
object is ``name``, which is the name of the route that matched.
.. note::
@@ -858,41 +828,39 @@
Routing Examples
----------------
Let's check out some examples of how route configuration statements
might be commonly declared, and what will happen if they are matched
by the information present in a request.
Let's check out some examples of how route configuration statements might be
commonly declared, and what will happen if they are matched by the
information present in a request.
.. _urldispatch_example1:
Example 1
~~~~~~~~~
The simplest route declaration which configures a route match to
*directly* result in a particular view callable being invoked:
The simplest route declaration which configures a route match to *directly*
result in a particular view callable being invoked:
.. code-block:: python
   :linenos:
    config.add_route('idea', 'site/{id}', view='mypackage.views.site_view')
When a route configuration with a ``view`` attribute is added to the
system, and an incoming request matches the *pattern* of the route
configuration, the :term:`view callable` named as the ``view``
attribute of the route configuration will be invoked.
When a route configuration with a ``view`` attribute is added to the system,
and an incoming request matches the *pattern* of the route configuration, the
:term:`view callable` named as the ``view`` attribute of the route
configuration will be invoked.
In the case of the above example, when the URL of a request matches
``/site/{id}``, the view callable at the Python dotted path name
``mypackage.views.site_view`` will be called with the request.  In
other words, we've associated a view callable directly with a route
pattern.
``mypackage.views.site_view`` will be called with the request.  In other
words, we've associated a view callable directly with a route pattern.
When the ``/site/{id}`` route pattern matches during a request, the
``site_view`` view callable is invoked with that request as its sole
argument.  When this route matches, a ``matchdict`` will be generated
and attached to the request as ``request.matchdict``.  If the specific
URL matched is ``/site/1``, the ``matchdict`` will be a dictionary
with a single key, ``id``; the value will be the string ``'1'``, ex.:
``{'id':'1'}``.
argument.  When this route matches, a ``matchdict`` will be generated and
attached to the request as ``request.matchdict``.  If the specific URL
matched is ``/site/1``, the ``matchdict`` will be a dictionary with a single
key, ``id``; the value will be the string ``'1'``, ex.: ``{'id':'1'}``.
The ``mypackage.views`` module referred to above might look like so:
@@ -904,17 +872,16 @@
   def site_view(request):
       return Response(request.matchdict['id'])
The view has access to the matchdict directly via the request, and can
access variables within it that match keys present as a result of the
route pattern.
The view has access to the matchdict directly via the request, and can access
variables within it that match keys present as a result of the route pattern.
See :ref:`views_chapter` for more information about views.
Example 2
~~~~~~~~~
Below is an example of a more complicated set of route statements you
might add to your application:
Below is an example of a more complicated set of route statements you might
add to your application:
.. code-block:: python
   :linenos:
@@ -923,8 +890,8 @@
   config.add_route('user', 'users/{user}', view='mypackage.views.user_view')
   config.add_route('tag', 'tags/{tags}', view='mypackage.views.tag_view')
The above configuration will allow :app:`Pyramid` to service URLs
in these forms:
The above configuration will allow :app:`Pyramid` to service URLs in these
forms:
.. code-block:: text
@@ -947,17 +914,17 @@
  For the specific URL ``/tags/1``, the ``matchdict`` generated and attached
  to the :term:`request` will consist of ``{'tag':'1'}``.
In this example we've again associated each of our routes with a
:term:`view callable` directly.  In all cases, the request, which will
have a ``matchdict`` attribute detailing the information found in the
URL by the process will be passed to the view callable.
In this example we've again associated each of our routes with a :term:`view
callable` directly.  In all cases, the request, which will have a
``matchdict`` attribute detailing the information found in the URL by the
process will be passed to the view callable.
Example 3
~~~~~~~~~
The context resource object passed in to a view found as the result of URL
dispatch will, by default, be an instance of the object returned by the
:term:`root factory` configured at startup time (the ``root_factory``
The :term:`context` resource object passed in to a view found as the result
of URL dispatch will, by default, be an instance of the object returned by
the :term:`root factory` configured at startup time (the ``root_factory``
argument to the :term:`Configurator` used to configure the application).
You can override this behavior by passing in a ``factory`` argument to the
@@ -992,9 +959,9 @@
Example 4
~~~~~~~~~
It is possible to create a route declaration without a ``view``
attribute, but associate the route with a :term:`view callable` using
a ``view`` declaration.
It is possible to create a route declaration without a ``view`` attribute,
but associate the route with a :term:`view callable` using a ``view``
declaration.
.. code-block:: python
   :linenos:
@@ -1002,21 +969,20 @@
   config.add_route('idea', 'site/{id}')
   config.add_view(route_name='idea', view='mypackage.views.site_view')
This set of configuration parameters creates a configuration
completely equivalent to this example provided in
:ref:`urldispatch_example1`:
This set of configuration parameters creates a configuration completely
equivalent to this example provided in :ref:`urldispatch_example1`:
.. code-block:: python
   :linenos:
   config.add_route('idea', 'site/{id}', view='mypackage.views.site_view')
In fact, the spelling which names a ``view`` attribute is just
syntactic sugar for the more verbose spelling which contains separate
view and route registrations.
In fact, the spelling which names a ``view`` attribute is just syntactic
sugar for the more verbose spelling which contains separate view and route
registrations.
More uses for this style of associating views with routes are explored
in :ref:`hybrid_chapter`.
More uses for this style of associating views with routes are explored in
:ref:`hybrid_chapter`.
.. index::
   single: matching the root URL
@@ -1059,11 +1025,9 @@
   from pyramid.url import route_url
   url = route_url('foo', request, a='1', b='2', c='3')
This would return something like the string
``http://example.com/1/2/3`` (at least if the current protocol and
hostname implied ``http:/example.com``).  See the
:func:`pyramid.url.route_url` API documentation for more
information.
This would return something like the string ``http://example.com/1/2/3`` (at
least if the current protocol and hostname implied ``http:/example.com``).
See the :func:`pyramid.url.route_url` API documentation for more information.
.. index::
   single: redirecting to slash-appended routes
@@ -1074,19 +1038,18 @@
------------------------------------
For behavior like Django's ``APPEND_SLASH=True``, use the
:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not
Found view` in your application.  Defining this view as the :term:`Not
Found view` is a way to automatically redirect requests where the URL
lacks a trailing slash, but requires one to match the proper route.
When configured, along with at least one other route in your
application, this view will be invoked if the value of ``PATH_INFO``
does not already end in a slash, and if the value of ``PATH_INFO``
*plus* a slash matches any route's pattern.  In this case it does an
HTTP redirect to the slash-appended ``PATH_INFO``.
:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not Found
view` in your application.  Defining this view as the :term:`Not Found view`
is a way to automatically redirect requests where the URL lacks a trailing
slash, but requires one to match the proper route.  When configured, along
with at least one other route in your application, this view will be invoked
if the value of ``PATH_INFO`` does not already end in a slash, and if the
value of ``PATH_INFO`` *plus* a slash matches any route's pattern.  In this
case it does an HTTP redirect to the slash-appended ``PATH_INFO``.
Let's use an example, because this behavior is a bit magical. If the
``append_slash_notfound_view`` is configured in your application and
your route configuration looks like so:
``append_slash_notfound_view`` is configured in your application and your
route configuration looks like so:
.. code-block:: python
   :linenos:
@@ -1094,17 +1057,17 @@
   config.add_route('noslash', 'no_slash', view='myproject.views.no_slash')
   config.add_route('hasslash', 'has_slash/', view='myproject.views.has_slash')
If a request enters the application with the ``PATH_INFO``
value of ``/has_slash/``, the second route will match.  If a request
enters the application with the ``PATH_INFO`` value of ``/has_slash``,
a route *will* be found by the slash-appending not found view.  An HTTP
redirect to ``/has_slash/`` will be returned to the user's browser.
If a request enters the application with the ``PATH_INFO`` value of
``/has_slash/``, the second route will match.  If a request enters the
application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be
found by the slash-appending not found view.  An HTTP redirect to
``/has_slash/`` will be returned to the user's browser.
If a request enters the application with the ``PATH_INFO`` value of
``/no_slash``, the first route will match.  However, if a request enters the
application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route
will match, and the slash-appending not found view will *not* find a
matching route with an appended slash.
application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route will
match, and the slash-appending not found view will *not* find a matching
route with an appended slash.
.. warning::
@@ -1123,29 +1086,27 @@
                   view='pyramid.view.append_slash_notfound_view')
See :ref:`view_module` and :ref:`changing_the_notfound_view` for more
information about the slash-appending not found view and for a more
general description of how to configure a not found view.
information about the slash-appending not found view and for a more general
description of how to configure a not found view.
Custom Not Found View With Slash Appended Routes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There can only be one :term:`Not Found view` in any :app:`Pyramid`
application.  Even if you use
:func:`pyramid.view.append_slash_notfound_view` as the Not Found
view, :app:`Pyramid` still must generate a ``404 Not Found``
response when it cannot redirect to a slash-appended URL; this not
found response will be visible to site users.
application.  Even if you use :func:`pyramid.view.append_slash_notfound_view`
as the Not Found view, :app:`Pyramid` still must generate a ``404 Not Found``
response when it cannot redirect to a slash-appended URL; this not found
response will be visible to site users.
If you don't care what this 404 response looks like, and only you need
redirections to slash-appended route URLs, you may use the
:func:`pyramid.view.append_slash_notfound_view` object as the Not
Found view as described above.  However, if you wish to use a *custom*
notfound view callable when a URL cannot be redirected to a
slash-appended URL, you may wish to use an instance of the
:class:`pyramid.view.AppendSlashNotFoundViewFactory` class as the
Not Found view, supplying a :term:`view callable` to be used as the
custom notfound view as the first argument to its constructor.  For
instance:
:func:`pyramid.view.append_slash_notfound_view` object as the Not Found view
as described above.  However, if you wish to use a *custom* notfound view
callable when a URL cannot be redirected to a slash-appended URL, you may
wish to use an instance of the
:class:`pyramid.view.AppendSlashNotFoundViewFactory` class as the Not Found
view, supplying a :term:`view callable` to be used as the custom notfound
view as the first argument to its constructor.  For instance:
.. code-block:: python
     :linenos:
@@ -1159,9 +1120,9 @@
     custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view)
     config.add_view(custom_append_slash, context=NotFound)
The ``notfound_view`` supplied must adhere to the two-argument view
callable calling convention of ``(context, request)`` (``context``
will be the exception object).
The ``notfound_view`` supplied must adhere to the two-argument view callable
calling convention of ``(context, request)`` (``context`` will be the
exception object).
.. _cleaning_up_after_a_request:
@@ -1169,22 +1130,21 @@
---------------------------
Sometimes it's required that some cleanup be performed at the end of a
request when a database connection is involved.  When
:term:`traversal` is used, this cleanup is often done as a side effect
of the traversal :term:`root factory`.  Often the root factory will
insert an object into the WSGI environment that performs some cleanup
when its ``__del__`` method is called.  When URL dispatch is used,
however, no special root factory is required, so sometimes that option
is not open to you.
request when a database connection is involved.  When :term:`traversal` is
used, this cleanup is often done as a side effect of the traversal
:term:`root factory`.  Often the root factory will insert an object into the
WSGI environment that performs some cleanup when its ``__del__`` method is
called.  When URL dispatch is used, however, no special root factory is
required, so sometimes that option is not open to you.
Instead of putting this cleanup logic in the root factory, however,
you can cause a subscriber to be fired when a new request is detected;
the subscriber can do this work.
Instead of putting this cleanup logic in the root factory, however, you can
cause a subscriber to be fired when a new request is detected; the subscriber
can do this work.
For example, let's say you have a ``mypackage`` :app:`Pyramid`
application package that uses SQLAlchemy, and you'd like the current
SQLAlchemy database session to be removed after each request.  Put the
following in the ``mypackage.run`` module:
For example, let's say you have a ``mypackage`` :app:`Pyramid` application
package that uses SQLAlchemy, and you'd like the current SQLAlchemy database
session to be removed after each request.  Put the following in the
``mypackage.__init__`` module:
.. ignore-next-block
.. code-block:: python
@@ -1297,4 +1257,3 @@
A tutorial showing how :term:`URL dispatch` can be used to create a
:app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`.