diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/api/interfaces.rst | 2 | ||||
| -rw-r--r-- | docs/api/request.rst | 33 | ||||
| -rw-r--r-- | docs/designdefense.rst | 4 | ||||
| -rw-r--r-- | docs/glossary.rst | 12 | ||||
| -rw-r--r-- | docs/narr/assets.rst | 2 | ||||
| -rw-r--r-- | docs/narr/hooks.rst | 134 | ||||
| -rw-r--r-- | docs/narr/renderers.rst | 2 | ||||
| -rw-r--r-- | docs/narr/router.rst | 6 | ||||
| -rw-r--r-- | docs/narr/views.rst | 36 | ||||
| -rw-r--r-- | docs/narr/webob.rst | 66 | ||||
| -rw-r--r-- | docs/tutorials/wiki/definingviews.rst | 10 | ||||
| -rw-r--r-- | docs/tutorials/wiki2/definingviews.rst | 3 |
12 files changed, 185 insertions, 125 deletions
diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst index 3a60fa4dc..51a1963b5 100644 --- a/docs/api/interfaces.rst +++ b/docs/api/interfaces.rst @@ -57,6 +57,6 @@ Other Interfaces .. autointerface:: IMultiDict :members: - .. autointerface:: IResponder + .. autointerface:: IResponse :members: diff --git a/docs/api/request.rst b/docs/api/request.rst index 8cb424658..27ce395ac 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -107,7 +107,9 @@ return {'text':'Value that will be used by the renderer'} Mutations to this response object will be preserved in the response sent - to the client after rendering. + to the client after rendering. For more information about using + ``request.response`` in conjunction with a renderer, see + :ref:`request_response_attr`. Non-renderer code can also make use of request.response instead of creating a response "by hand". For example, in view code:: @@ -162,20 +164,21 @@ .. attribute:: response_* - .. warning:: As of Pyramid 1.1, assignment to ``response_*`` attrs are - deprecated. Assigning to one will cause a deprecation warning to be - emitted. Instead of assigning ``response_*`` attributes to the - request, use API of the the :attr:`pyramid.request.Request.response` - object (exposed to view code as ``request.response``) to influence - response behavior. - - You can set attributes on a :class:`pyramid.request.Request` which will - influence the behavor of *rendered* responses (views which use a - :term:`renderer` and which don't directly return a response). These - attributes begin with ``response_``, such as ``response_headerlist``. If - you need to influence response values from a view that uses a renderer - (such as the status code, a header, the content type, etc) see, - :ref:`response_prefixed_attrs`. + In Pyramid 1.0, you could set attributes on a + :class:`pyramid.request.Request` which influenced the behavor of + *rendered* responses (views which use a :term:`renderer` and which + don't directly return a response). These attributes began with + ``response_``, such as ``response_headerlist``. If you needed to + influence response values from a view that uses a renderer (such as the + status code, a header, the content type, etc) you would set these + attributes. See :ref:`response_prefixed_attrs` for further discussion. + As of Pyramid 1.1, assignment to ``response_*`` attrs are deprecated. + Assigning to one is still supported but will cause a deprecation + warning to be emitted, and eventually the feature will be removed. For + new code, instead of assigning ``response_*`` attributes to the + request, use API of the the :attr:`pyramid.request.Request.response` + object (exposed to view code as ``request.response``) to influence + rendered response behavior. .. note:: diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 136b9c5de..de6c0af33 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -428,7 +428,7 @@ allowing people to define "custom" view predicates: :linenos: from pyramid.view import view_config - from webob import Response + from pyramid.response import Response def subpath(context, request): return request.subpath and request.subpath[0] == 'abc' @@ -1497,7 +1497,7 @@ comments take into account what we've discussed in the .. code-block:: python :linenos: - from webob import Response # explicit response objects, no TL + from pyramid.response import Response # explicit response objects, no TL from paste.httpserver import serve # explicitly WSGI def hello_world(request): # accepts a request; no request thread local reqd diff --git a/docs/glossary.rst b/docs/glossary.rst index 079a069b4..d3ba9a545 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -16,12 +16,12 @@ Glossary positional argument, returns a ``WebOb`` compatible request. response - An object that has three attributes: ``app_iter`` (representing an - iterable body), ``headerlist`` (representing the http headers sent - to the user agent), and ``status`` (representing the http status - string sent to the user agent). This is the interface defined for - ``WebOb`` response objects. See :ref:`webob_chapter` for - information about response objects. + An object returned by a :term:`view callable` that represents response + data returned to the requesting user agent. It must implements the + :class:`pyramid.interfaces.IResponse` interface. A response object is + typically an instance of the :class:`pyramid.response.Response` class or + a subclass such as :class:`pyramid.httpexceptions.HTTPFound`. See + :ref:`webob_chapter` for information about response objects. Repoze "Repoze" is essentially a "brand" of software developed by `Agendaless diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 8d0e7058c..0d50b0106 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -358,7 +358,7 @@ do so, do things "by hand". First define the view callable. :linenos: import os - from webob import Response + from pyramid.response import Response def favicon_view(request): here = os.path.dirname(__file__) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b6a781417..0db8ce5e0 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -523,41 +523,103 @@ The default context URL generator is available for perusal as the class :term:`Pylons` GitHub Pyramid repository. .. index:: - single: IResponder - -.. _using_iresponder: - -Changing How Pyramid Treats Response Objects --------------------------------------------- - -It is possible to control how the Pyramid :term:`router` calls the WSGI -``start_response`` callable and obtains the WSGI ``app_iter`` based on -adapting the response object to the :class: `pyramid.interfaces.IResponder` -interface. The default responder uses the ``__call__`` method of a response -object, passing it the WSGI environ and the WSGI ``start_response`` callable -(the response is assumed to be a WSGI application). To override the -responder:: - - from pyramid.interfaces import IResponder - from pyramid.response import Response - from myapp import MyResponder - - config.registry.registerAdapter(MyResponder, (Response,), - IResponder, name='') - -Overriding makes it possible to reuse response object implementations which -have, for example, the ``app_iter``, ``headerlist`` and ``status`` attributes -of an object returned as a response instead of trying to use the object's -``__call__`` method:: - - class MyResponder(object): - def __init__(self, response): - """ Obtain a reference to the response """ - self.response = response - def __call__(self, request, start_response): - """ Call start_response and return an app_iter """ - start_response(self.response.status, self.response.headerlist) - return self.response.app_iter + single: IResponse + +.. _using_iresponse: + +Changing How Pyramid Treats View Responses +------------------------------------------ + +It is possible to control how Pyramid treats the result of calling a view +callable on a per-type basis by using a hook involving +:class:`pyramid.interfaces.IResponse`. + +.. note:: This feature is new as of Pyramid 1.1. + +Pyramid, in various places, adapts the result of calling a view callable to +the :class:`~pyramid.interfaces.IResponse` interface to ensure that the +object returned by the view callable is a "true" response object. The vast +majority of time, the result of this adaptation is the result object itself, +as view callables written by "civilians" who read the narrative documentation +contained in this manual will always return something that implements the +:class:`~pyramid.interfaces.IResponse` interface. Most typically, this will +be an instance of the :class:`pyramid.response.Response` class or a subclass. +If a civilian returns a non-Response object from a view callable that isn't +configured to use a :term:`renderer`, he will typically expect the router to +raise an error. However, you can hook Pyramid in such a way that users can +return arbitrary values from a view callable by providing an adapter which +converts the arbitrary return value into something that implements +:class:`~pyramid.interfaces.IResponse`. + +For example, if you'd like to allow view callables to return bare string +objects (without requiring a a :term:`renderer` to convert a string to a +response object), you can register an adapter which converts the string to a +Response: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import IResponse + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + return response + + # config is an instance of pyramid.config.Configurator + + config.registry.registerAdapter(string_response_adapter, (str,), + IResponse) + +Likewise, if you want to be able to return a simplified kind of response +object from view callables, you can use the IResponse hook to register an +adapter to the more complex IResponse interface: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import IResponse + from pyramid.response import Response + + class SimpleResponse(object): + def __init__(self, body): + self.body = body + + def simple_response_adapter(simple_response): + response = Response(simple_response.body) + return response + + # config is an instance of pyramid.config.Configurator + + config.registry.registerAdapter(simple_response_adapter, + (SimpleResponse,), + IResponse) + +If you want to implement your own Response object instead of using the +:class:`pyramid.response.Response` object in any capacity at all, you'll have +to make sure the object implements every attribute and method outlined in +:class:`pyramid.interfaces.IResponse` *and* you'll have to ensure that it's +marked up with ``zope.interface.implements(IResponse)``: + + from pyramid.interfaces import IResponse + from zope.interface import implements + + class MyResponse(object): + implements(IResponse) + # ... an implementation of every method and attribute + # documented in IResponse should follow ... + +When an alternate response object implementation is returned by a view +callable, if that object asserts that it implements +:class:`~pyramid.interfaces.IResponse` (via +``zope.interface.implements(IResponse)``) , an adapter needn't be registered +for the object; Pyramid will use it directly. + +An IResponse adapter for ``webob.Response`` (as opposed to +:class:`pyramid.response.Response`) is registered by Pyramid by default at +startup time, as by their nature, instances of this class (and instances of +subclasses of the class) will natively provide IResponse. The adapter +registered for ``webob.Response`` simply returns the response object. .. index:: single: view mapper @@ -628,7 +690,7 @@ A user might make use of these framework components like so: # user application - from webob import Response + from pyramid.response import Response from pyramid.config import Configurator import pyramid_handlers from paste.httpserver import serve diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 99ee14908..c4a37c23d 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -416,7 +416,7 @@ effect, you must return ``request.response``: For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of -``request.response``, see :class:`pyramid.response.Response`. +``request.response``, see :attr:`pyramid.request.Request.response`. .. _response_prefixed_attrs: diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 30d54767e..0812f7ec7 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -115,9 +115,9 @@ processing? any :term:`response callback` functions attached via :meth:`~pyramid.request.Request.add_response_callback`. A :class:`~pyramid.events.NewResponse` :term:`event` is then sent to any - subscribers. The response object's ``app_iter``, ``status``, and - ``headerlist`` attributes are then used to generate a WSGI response. The - response is sent back to the upstream WSGI server. + subscribers. The response object's ``__call__`` method is then used to + generate a WSGI response. The response is sent back to the upstream WSGI + server. #. :app:`Pyramid` will attempt to execute any :term:`finished callback` functions attached via diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 990828f80..e3d0a37e5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -230,29 +230,19 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -You don't need to use :class:`~pyramid.response.Response` to represent a -response. A view can actually return any object that has a ``__call__`` -method that implements the :term:`WSGI` application call interface. For -example, an instance of the following class could be successfully returned by -a view callable as a response object: - -.. code-block:: python - :linenos: - - class SimpleResponse(object): - def __call__(self, environ, start_response): - """ Call the ``start_response`` callback and return - an iterable """ - body = 'Hello World!' - headers = [('Content-Type', 'text/plain'), - ('Content-Length', str(len(body)))] - start_response('200 OK', headers) - return [body] - -:app:`Pyramid` provides a range of different "exception" classes which can -act as response objects too. For example, an instance of the class -:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object -(see :ref:`http_exceptions` and ref:`http_redirect`). +:app:`Pyramid` provides a range of different "exception" classes which +inherit from :class:`pyramid.response.Response`. For example, an instance of +the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response +object because it inherits from :class:`~pyramid.response.Response`. For +examples, see :ref:`http_exceptions` and ref:`http_redirect`. + +You can also return objects from view callables that aren't instances of (or +instances of classes which are subclasses of) +:class:`pyramid.response.Response` in various circumstances. This can be +helpful when writing tests and when attempting to share code between view +callables. See :ref:`renderers_chapter` for the common way to allow for +this. A much less common way to allow for view callables to return +non-Response objects is documented in :ref:`using_iresponse`. .. index:: single: view exceptions diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 70ab5eea8..0ff8e1de7 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -10,15 +10,15 @@ Request and Response Objects .. note:: This chapter is adapted from a portion of the :term:`WebOb` documentation, originally written by Ian Bicking. -:app:`Pyramid` uses the :term:`WebOb` package to supply +:app:`Pyramid` uses the :term:`WebOb` package as a basis for its :term:`request` and :term:`response` object implementations. The -:term:`request` object that is passed to a :app:`Pyramid` -:term:`view` is an instance of the :class:`pyramid.request.Request` -class, which is a subclass of :class:`webob.Request`. The -:term:`response` returned from a :app:`Pyramid` :term:`view` -:term:`renderer` is an instance of the :mod:`webob.Response` class. -Users can also return an instance of :mod:`webob.Response` directly -from a view as necessary. +:term:`request` object that is passed to a :app:`Pyramid` :term:`view` is an +instance of the :class:`pyramid.request.Request` class, which is a subclass +of :class:`webob.Request`. The :term:`response` returned from a +:app:`Pyramid` :term:`view` :term:`renderer` is an instance of the +:mod:`pyramid.response.Response` class, which is a subclass of the +:class:`webob.Response` class. Users can also return an instance of +:class:`pyramid.response.Response` directly from a view as necessary. WebOb is a project separate from :app:`Pyramid` with a separate set of authors and a fully separate `set of documentation @@ -26,16 +26,15 @@ authors and a fully separate `set of documentation standard WebOb request, which is documented in the :ref:`request_module` API documentation. -WebOb provides objects for HTTP requests and responses. Specifically -it does this by wrapping the `WSGI <http://wsgi.org>`_ request -environment and response status/headers/app_iter (body). +WebOb provides objects for HTTP requests and responses. Specifically it does +this by wrapping the `WSGI <http://wsgi.org>`_ request environment and +response status, header list, and app_iter (body) values. -WebOb request and response objects provide many conveniences for -parsing WSGI requests and forming WSGI responses. WebOb is a nice way -to represent "raw" WSGI requests and responses; however, we won't -cover that use case in this document, as users of :app:`Pyramid` -don't typically need to use the WSGI-related features of WebOb -directly. The `reference documentation +WebOb request and response objects provide many conveniences for parsing WSGI +requests and forming WSGI responses. WebOb is a nice way to represent "raw" +WSGI requests and responses; however, we won't cover that use case in this +document, as users of :app:`Pyramid` don't typically need to use the +WSGI-related features of WebOb directly. The `reference documentation <http://pythonpaste.org/webob/reference.html>`_ shows many examples of creating requests and using response objects in this manner, however. @@ -170,9 +169,9 @@ of the request. I'll show various values for an example URL Methods +++++++ -There are `several methods -<http://pythonpaste.org/webob/class-webob.Request.html#__init__>`_ but -only a few you'll use often: +There are methods of request objects documented in +:class:`pyramid.request.Request` but you'll find that you won't use very many +of them. Here are a couple that might be useful: ``Request.blank(base_url)``: Creates a new request with blank information, based at the given @@ -183,9 +182,9 @@ only a few you'll use often: subrequests). ``req.get_response(wsgi_application)``: - This method calls the given WSGI application with this request, - and returns a `Response`_ object. You can also use this for - subrequests, or testing. + This method calls the given WSGI application with this request, and + returns a :class:`pyramid.response.Response` object. You can also use + this for subrequests, or testing. .. index:: single: request (and unicode) @@ -259,8 +258,10 @@ Response ~~~~~~~~ The :app:`Pyramid` response object can be imported as -:class:`pyramid.response.Response`. This import location is merely a facade -for its original location: ``webob.Response``. +:class:`pyramid.response.Response`. This class is a subclass of the +``webob.Response`` class. The subclass does not add or change any +functionality, so the WebOb Response documentation will be completely +relevant for this class as well. A response object has three fundamental parts: @@ -283,8 +284,8 @@ A response object has three fundamental parts: ``response.body_file`` (a file-like object; writing to it appends to ``app_iter``). -Everything else in the object derives from this underlying state. -Here's the highlights: +Everything else in the object typically derives from this underlying state. +Here are some highlights: ``response.content_type`` The content type *not* including the ``charset`` parameter. @@ -359,11 +360,12 @@ Exception Responses +++++++++++++++++++ To facilitate error responses like ``404 Not Found``, the module -:mod:`webob.exc` contains classes for each kind of error response. These -include boring, but appropriate error bodies. The exceptions exposed by this -module, when used under :app:`Pyramid`, should be imported from the -:mod:`pyramid.httpexceptions` module. This import location contains -subclasses and replacements that mirror those in the original ``webob.exc``. +:mod:`pyramid.httpexceptions` contains classes for each kind of error +response. These include boring, but appropriate error bodies. The +exceptions exposed by this module, when used under :app:`Pyramid`, should be +imported from the :mod:`pyramid.httpexceptions` module. This import location +contains subclasses and replacements that mirror those in the ``webob.exc`` +module. Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the reason for the error. For instance, diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index b6c083bbf..92a3da09c 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -84,10 +84,12 @@ No renderer is necessary when a view returns a response object. The ``view_wiki`` view callable always redirects to the URL of a Page resource named "FrontPage". To do so, it returns an instance of the :class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement -the WebOb :term:`response` interface). The :func:`pyramid.url.resource_url` -API. :func:`pyramid.url.resource_url` constructs a URL to the ``FrontPage`` -page resource (e.g. ``http://localhost:6543/FrontPage``), and uses it as the -"location" of the HTTPFound response, forming an HTTP redirect. +the :class:`pyramid.interfaces.IResponse` interface like +:class:`pyramid.response.Response` does). The +:func:`pyramid.url.resource_url` API. :func:`pyramid.url.resource_url` +constructs a URL to the ``FrontPage`` page resource +(e.g. ``http://localhost:6543/FrontPage``), and uses it as the "location" of +the HTTPFound response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 832f90b92..43cbc3483 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -91,7 +91,8 @@ path to our "FrontPage". The ``view_wiki`` function returns an instance of the :class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement -the WebOb :term:`response` interface), It will use the +the :class:`pyramid.interfaces.IResponse` interface like +:class:`pyramid.response.Response` does), It will use the :func:`pyramid.url.route_url` API to construct a URL to the ``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), and will use it as the "location" of the HTTPFound response, forming an HTTP redirect. |
