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