1.. index::
2   single: request processing
3   single: request
4   single: router
5   single: request lifecycle
6
7.. _router_chapter:
8
9Request Processing
10==================
11
12.. image:: ../_static/pyramid_request_processing.*
13   :alt: Request Processing
14
15Once a :app:`Pyramid` application is up and running, it is ready to accept
16requests and return responses.  What happens from the time a :term:`WSGI`
17request enters a :app:`Pyramid` application through to the point that
18:app:`Pyramid` hands off a response back to WSGI for upstream processing?
19
20#. A user initiates a request from their browser to the hostname and port
21   number of the WSGI server used by the :app:`Pyramid` application.
22
23#. The WSGI server used by the :app:`Pyramid` application passes the WSGI
24   environment to the ``__call__`` method of the :app:`Pyramid` :term:`router`
25   object.
26
27#. A :term:`request` object is created based on the WSGI environment.
28
29#. The :term:`application registry` and the :term:`request` object created in
30   the last step are pushed on to the :term:`thread local` stack that
31   :app:`Pyramid` uses to allow the functions named
32   :func:`~pyramid.threadlocal.get_current_request` and
33   :func:`~pyramid.threadlocal.get_current_registry` to work.
34
35#. A :class:`~pyramid.events.NewRequest` :term:`event` is sent to any
36   subscribers.
37
38#. If any :term:`route` has been defined within application configuration, the
39   :app:`Pyramid` :term:`router` calls a :term:`URL dispatch` "route mapper."
40   The job of the mapper is to examine the request to determine whether any
41   user-defined :term:`route` matches the current WSGI environment.  The
42   :term:`router` passes the request as an argument to the mapper.
43
44#. If any route matches, the route mapper adds the attributes ``matchdict``
45   and ``matched_route`` to the request object. The former contains a
46   dictionary representing the matched dynamic elements of the request's
47   ``PATH_INFO`` value, and the latter contains the
48   :class:`~pyramid.interfaces.IRoute` object representing the route which
49   matched.
50
51#. A :class:`~pyramid.events.BeforeTraversal` :term:`event` is sent to any
52   subscribers.
53
54#. Continuing, if any route matches, the root object associated with the found
55   route is generated. If the :term:`route configuration` which matched has an
56   associated ``factory`` argument, then this factory is used to generate the
57   root object; otherwise a default :term:`root factory` is used.
58
59   However, if no route matches, and if a ``root_factory`` argument was passed
60   to the :term:`Configurator` constructor, that callable is used to generate
61   the root object. If the ``root_factory`` argument passed to the
62   Configurator constructor was ``None``, a default root factory is used to
63   generate a root object.
64
65#. The :app:`Pyramid` router calls a "traverser" function with the root object
66   and the request.  The traverser function attempts to traverse the root
67   object (using any existing ``__getitem__`` on the root object and
68   subobjects) to find a :term:`context`.  If the root object has no
69   ``__getitem__`` method, the root itself is assumed to be the context. The
70   exact traversal algorithm is described in :ref:`traversal_chapter`. The
71   traverser function returns a dictionary, which contains a :term:`context`
72   and a :term:`view name` as well as other ancillary information.
73
74#. The request is decorated with various names returned from the traverser
75   (such as ``context``, ``view_name``, and so forth), so they can be accessed
76   via, for example, ``request.context`` within :term:`view` code.
77
78#. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any
79   subscribers.
80
81#. :app:`Pyramid` looks up a :term:`view` callable using the context, the
82   request, and the view name.  If a view callable doesn't exist for this
83   combination of objects (based on the type of the context, the type of the
84   request, and the value of the view name, and any :term:`predicate`
85   attributes applied to the view configuration), :app:`Pyramid` raises a
86   :class:`~pyramid.httpexceptions.HTTPNotFound` exception, which is meant to
87   be caught by a surrounding :term:`exception view`.
88
89#. If a view callable was found, :app:`Pyramid` attempts to call it.  If an
90   :term:`authorization policy` is in use, and the view configuration is
91   protected by a :term:`permission`, :app:`Pyramid` determines whether the
92   view callable being asked for can be executed by the requesting user based
93   on credential information in the request and security information attached
94   to the context.  If the view execution is allowed, :app:`Pyramid` calls the
95   view callable to obtain a response.  If view execution is forbidden,
96   :app:`Pyramid` raises a :class:`~pyramid.httpexceptions.HTTPForbidden`
97   exception.
98
99#. If any exception is raised within a :term:`root factory`, by
100   :term:`traversal`, by a :term:`view callable`, or by :app:`Pyramid` itself
101   (such as when it raises :class:`~pyramid.httpexceptions.HTTPNotFound` or
102   :class:`~pyramid.httpexceptions.HTTPForbidden`), the router catches the
103   exception, and attaches it to the request as the ``exception`` attribute.
104   It then attempts to find a :term:`exception view` for the exception that was
105   caught.  If it finds an exception view callable, that callable is called,
106   and is presumed to generate a response.  If an :term:`exception view` that
107   matches the exception cannot be found, the exception is reraised.
108
109#. The following steps occur only when a :term:`response` could be successfully
110   generated by a normal :term:`view callable` or an :term:`exception view`
111   callable.  :app:`Pyramid` will attempt to execute any :term:`response
112   callback` functions attached via
113   :meth:`~pyramid.request.Request.add_response_callback`. A
114   :class:`~pyramid.events.NewResponse` :term:`event` is then sent to any
115   subscribers.  The response object's ``__call__`` method is then used to
116   generate a WSGI response.  The response is sent back to the upstream WSGI
117   server.
118
119#. :app:`Pyramid` will attempt to execute any :term:`finished callback`
120   functions attached via
121   :meth:`~pyramid.request.Request.add_finished_callback`.
122
123#. The :term:`thread local` stack is popped.
124
125.. image:: ../_static/pyramid_router.*
126   :alt: Pyramid Router
127
128This is a very high-level overview that leaves out various details.  For more
129detail about subsystems invoked by the :app:`Pyramid` router, such as
130traversal, URL dispatch, views, and event processing, see
131:ref:`urldispatch_chapter`, :ref:`views_chapter`, and :ref:`events_chapter`.
132