- Remove IResponder abstraction in favor of more general IResponse
abstraction.
- It is now possible to return an arbitrary object from a Pyramid view
callable even if a renderer is not used, as long as a suitable adapter to
``pyramid.interfaces.IResponse`` is registered for the type of the returned
object. See the section in the Hooks chapter of the documentation entitled
"Changing How Pyramid Treats View Responses".
- The Pyramid router now, by default, expects response objects returned from
view callables to implement the ``pyramid.interfaces.IResponse`` interface.
Unlike the Pyramid 1.0 version of this interface, objects which implement
IResponse now must define a ``__call__`` method that accepts ``environ``
and ``start_response``, and which returns an ``app_iter`` iterable, among
other things. Previously, it was possible to return any object which had
the three WebOb ``app_iter``, ``headerlist``, and ``status`` attributes as
a response, so this is a backwards incompatibility. It is possible to get
backwards compatibility back by registering an adapter to IResponse from
the type of object you're now returning from view callables. See the
section in the Hooks chapter of the documentation entitled "Changing How
Pyramid Treats View Responses".
- The ``pyramid.interfaces.IResponse`` interface is now much more extensive.
Previously it defined only ``app_iter``, ``status`` and ``headerlist``; now
it is basically intended to directly mirror the ``webob.Response`` API,
which has many methods and attributes.
- Documentation changes to support above.
| | |
| | | - The ``pyramid.request.Response`` class now has a ``RequestClass`` interface |
| | | which points at ``pyramid.response.Request``. |
| | | |
| | | - It is now possible to control how the Pyramid router calls the WSGI |
| | | ``start_response`` callable and obtains the WSGI ``app_iter`` based on |
| | | adapting the response object to the new ``pyramid.interfaces.IResponder`` |
| | | interface. See the section in the Hooks chapter of the documentation |
| | | entitled "Changing How Pyramid Treats Response Objects". |
| | | - It is now possible to return an arbitrary object from a Pyramid view |
| | | callable even if a renderer is not used, as long as a suitable adapter to |
| | | ``pyramid.interfaces.IResponse`` is registered for the type of the returned |
| | | object. See the section in the Hooks chapter of the documentation entitled |
| | | "Changing How Pyramid Treats View Responses". |
| | | |
| | | - The Pyramid router will now, by default, call the ``__call__`` method of |
| | | WebOb response objects when returning a WSGI response. This means that, |
| | |
| | | ``webob.response.Response`` (in order to directly implement the |
| | | ``pyramid.interfaces.IResponse`` interface). |
| | | |
| | | - The ``pyramid.interfaces.IResponse`` interface now includes a ``__call__`` |
| | | method which has the WSGI application call signature (and which expects an |
| | | iterable as a result). |
| | | Backwards Incompatibilities |
| | | --------------------------- |
| | | |
| | | - The Pyramid router now, by default, expects response objects returned from |
| | | views to implement the WSGI application interface (a ``__call__`` method |
| | | that accepts ``environ`` and ``start_response``, and which returns an |
| | | ``app_iter`` iterable). If such a method exists, Pyramid will now call it |
| | | in order to satisfy the WSGI request. Backwards compatibility code in the |
| | | default responder exists which will fall back to the older behavior, but |
| | | Pyramid will raise a deprecation warning if it is reached. See the section |
| | | in the Hooks chapter of the documentation entitled "Changing How Pyramid |
| | | Treats Response Objects" to default back to the older behavior, where the |
| | | ``app_iter``, ``headerlist``, and ``status`` attributes of the object were |
| | | consulted directly (without any indirection through ``__call__``) to |
| | | silence the deprecation warnings. |
| | | view callables to implement the ``pyramid.interfaces.IResponse`` interface. |
| | | Unlike the Pyramid 1.0 version of this interface, objects which implement |
| | | IResponse now must define a ``__call__`` method that accepts ``environ`` |
| | | and ``start_response``, and which returns an ``app_iter`` iterable, among |
| | | other things. Previously, it was possible to return any object which had |
| | | the three WebOb ``app_iter``, ``headerlist``, and ``status`` attributes as |
| | | a response, so this is a backwards incompatibility. It is possible to get |
| | | backwards compatibility back by registering an adapter to IResponse from |
| | | the type of object you're now returning from view callables. See the |
| | | section in the Hooks chapter of the documentation entitled "Changing How |
| | | Pyramid Treats View Responses". |
| | | |
| | | - The ``pyramid.interfaces.IResponse`` interface is now much more extensive. |
| | | Previously it defined only ``app_iter``, ``status`` and ``headerlist``; now |
| | | it is basically intended to directly mirror the ``webob.Response`` API, |
| | | which has many methods and attributes. |
| | | |
| | | Dependencies |
| | | ------------ |
| | |
| | | |
| | | - To subclass or not subclass http exceptions. |
| | | |
| | | - Depend on only __call__ interface or only 3-attr interface in builtin code |
| | | that deals with response objects. |
| | | - Flesh out IResponse interface. Attributes Used internally: unicode_body / |
| | | body / content_type / charset / cache_expires / headers/ |
| | | default_content_type / set_cookie / headerlist / app_iter / status / |
| | | __call__. |
| | | |
| | | - Figure out what to do with ``is_response``. |
| | | - Deprecate view.is_response? |
| | | |
| | | - Move is_response to response.py? |
| | | |
| | | - Make sure registering IResponse adapter for webob.Response doesn't make it |
| | | impossible to register an IResponse adapter for an interface that a |
| | | webob.Response happens to implement. |
| | | |
| | | - Run whatsitdoing tests. |
| | | |
| | | - Docs mention ``exception.args[0]`` as a way to get messages; check that |
| | | this works. |
| | | |
| | | - Deprecate response_foo attrs on request at attribute set time rather than |
| | | lookup time. |
| | | |
| | | Should-Have |
| | | ----------- |
| | | |
| | |
| | | .. autointerface:: IMultiDict |
| | | :members: |
| | | |
| | | .. autointerface:: IResponder |
| | | .. autointerface:: IResponse |
| | | :members: |
| | | |
| | |
| | | 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:: |
| | |
| | | |
| | | .. 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:: |
| | | |
| | |
| | | :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' |
| | |
| | | .. 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 |
| | |
| | | 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 |
| | |
| | | :linenos: |
| | | |
| | | import os |
| | | from webob import Response |
| | | from pyramid.response import Response |
| | | |
| | | def favicon_view(request): |
| | | here = os.path.dirname(__file__) |
| | |
| | | :term:`Pylons` GitHub Pyramid repository. |
| | | |
| | | .. index:: |
| | | single: IResponder |
| | | single: IResponse |
| | | |
| | | .. _using_iresponder: |
| | | .. _using_iresponse: |
| | | |
| | | Changing How Pyramid Treats Response Objects |
| | | -------------------------------------------- |
| | | Changing How Pyramid Treats View Responses |
| | | ------------------------------------------ |
| | | |
| | | 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:: |
| | | 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`. |
| | | |
| | | from pyramid.interfaces import IResponder |
| | | from pyramid.response import Response |
| | | from myapp import MyResponder |
| | | .. note:: This feature is new as of Pyramid 1.1. |
| | | |
| | | config.registry.registerAdapter(MyResponder, (Response,), |
| | | IResponder, name='') |
| | | 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`. |
| | | |
| | | 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:: |
| | | 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: |
| | | |
| | | 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 |
| | | .. 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 |
| | |
| | | |
| | | # user application |
| | | |
| | | from webob import Response |
| | | from pyramid.response import Response |
| | | from pyramid.config import Configurator |
| | | import pyramid_handlers |
| | | from paste.httpserver import serve |
| | |
| | | |
| | | 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: |
| | | |
| | |
| | | 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 |
| | |
| | | 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: |
| | | :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`. |
| | | |
| | | .. 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`). |
| | | 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 |
| | |
| | | .. 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 |
| | |
| | | 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. |
| | | |
| | |
| | | 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 |
| | |
| | | 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) |
| | |
| | | ~~~~~~~~ |
| | | |
| | | 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: |
| | | |
| | |
| | | ``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. |
| | |
| | | +++++++++++++++++++ |
| | | |
| | | 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, |
| | |
| | | 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 |
| | | ------------------------------- |
| | |
| | | |
| | | 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. |
| | |
| | | from zope.interface.interfaces import IInterface |
| | | from zope.interface import implements |
| | | from zope.interface import classProvides |
| | | from zope.interface import providedBy |
| | | |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | |
| | | from pyramid.interfaces import IRendererGlobalsFactory |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.interfaces import IRequestFactory |
| | | from pyramid.interfaces import IResponse |
| | | from pyramid.interfaces import IRootFactory |
| | | from pyramid.interfaces import IRouteRequest |
| | | from pyramid.interfaces import IRoutesMapper |
| | |
| | | from pyramid.urldispatch import RoutesMapper |
| | | from pyramid.util import DottedNameResolver |
| | | from pyramid.view import render_view_to_response |
| | | from pyramid.view import is_response |
| | | |
| | | DEFAULT_RENDERERS = ( |
| | | ('.mak', mako_renderer_factory), |
| | |
| | | def _fix_registry(self): |
| | | """ Fix up a ZCA component registry that is not a |
| | | pyramid.registry.Registry by adding analogues of ``has_listeners``, |
| | | and ``notify`` through monkey-patching.""" |
| | | ``notify``, ``queryAdapterOrSelf``, and ``registerSelfAdapter`` |
| | | through monkey-patching.""" |
| | | |
| | | _registry = self.registry |
| | | |
| | |
| | | |
| | | if not hasattr(_registry, 'has_listeners'): |
| | | _registry.has_listeners = True |
| | | |
| | | if not hasattr(_registry, 'queryAdapterOrSelf'): |
| | | def queryAdapterOrSelf(object, interface, name=u'', default=None): |
| | | provides = providedBy(object) |
| | | if not interface in provides: |
| | | return _registry.queryAdapter(object, interface, name=name, |
| | | default=default) |
| | | return object |
| | | _registry.queryAdapterOrSelf = queryAdapterOrSelf |
| | | |
| | | if not hasattr(_registry, 'registerSelfAdapter'): |
| | | def registerSelfAdapter(required=None, provided=None, |
| | | name=u'', info=u'', event=True): |
| | | return _registry.registerAdapter(lambda x: x, |
| | | required=required, |
| | | provided=provided, name=name, |
| | | info=info, event=event) |
| | | _registry.registerSelfAdapter = registerSelfAdapter |
| | | |
| | | def _make_context(self, autocommit=False): |
| | | context = PyramidConfigurationMachine() |
| | |
| | | self._fix_registry() |
| | | self._set_settings(settings) |
| | | self._set_root_factory(root_factory) |
| | | # cope with WebOb response objects that aren't decorated with IResponse |
| | | from webob import Response as WebobResponse |
| | | registry.registerSelfAdapter((WebobResponse,), IResponse) |
| | | debug_logger = self.maybe_dotted(debug_logger) |
| | | if debug_logger is None: |
| | | debug_logger = make_stream_logger('pyramid.debug', sys.stderr) |
| | |
| | | |
| | | def _rendered_view(context, request): |
| | | renderer = static_renderer |
| | | response = wrapped_view(context, request) |
| | | if not is_response(response): |
| | | result = wrapped_view(context, request) |
| | | registry = self.kw['registry'] |
| | | response = registry.queryAdapterOrSelf(result, IResponse) |
| | | if response is None: |
| | | attrs = getattr(request, '__dict__', {}) |
| | | if 'override_renderer' in attrs: |
| | | # renderer overridden by newrequest event or other |
| | | renderer_name = attrs.pop('override_renderer') |
| | | renderer = RendererHelper(name=renderer_name, |
| | | package=self.kw.get('package'), |
| | | registry = self.kw['registry']) |
| | | registry = registry) |
| | | if '__view__' in attrs: |
| | | view_inst = attrs.pop('__view__') |
| | | else: |
| | | view_inst = getattr(wrapped_view, '__original_view__', |
| | | wrapped_view) |
| | | return renderer.render_view(request, response, view_inst, |
| | | context) |
| | | response = renderer.render_view(request, result, view_inst, |
| | | context) |
| | | return response |
| | | |
| | | return _rendered_view |
| | |
| | | dictionary. This is similar to the kind of dictionary often used to |
| | | represent the variables in a web request. """ |
| | | |
| | | class IResponder(Interface): |
| | | """ Adapter from IResponse to an IResponder. See :ref:`using_iresponder` |
| | | for usage details. New in Pyramid 1.1. |
| | | """ |
| | | def __call__(self, request, start_response): |
| | | """ Call the WSGI ``start_response`` callable passed as |
| | | ``start_response`` and return an ``app_iter``.""" |
| | | |
| | | # internal interfaces |
| | | |
| | | class IRequest(Interface): |
| | |
| | | from zope.component.registry import Components |
| | | from zope.interface import providedBy |
| | | |
| | | from pyramid.interfaces import ISettings |
| | | |
| | |
| | | self.has_listeners = True |
| | | return result |
| | | |
| | | def registerSelfAdapter(self, required=None, provided=None, name=u'', |
| | | info=u'', event=True): |
| | | # registerAdapter analogue which always returns the object itself |
| | | # when required is matched |
| | | return self.registerAdapter(lambda x: x, required=required, |
| | | provided=provided, name=name, |
| | | info=info, event=event) |
| | | |
| | | def queryAdapterOrSelf(self, object, interface, name=u'', default=None): |
| | | # queryAdapter analogue which returns the object if it implements |
| | | # the interface, otherwise it will return an adaptation to the |
| | | # interface |
| | | provides = providedBy(object) |
| | | if not interface in provides: |
| | | return self.queryAdapter(object, interface, name=name, |
| | | default=default) |
| | | return object |
| | | |
| | | def registerHandler(self, *arg, **kw): |
| | | result = Components.registerHandler(self, *arg, **kw) |
| | | self.has_listeners = True |
| | |
| | | 'context':context, |
| | | 'request':request |
| | | } |
| | | return self.render_to_response(response, system, |
| | | request=request) |
| | | |
| | | return self.render_to_response(response, system, request=request) |
| | | |
| | | def render(self, value, system_values, request=None): |
| | | renderer = self.renderer |
| | |
| | | from webob import BaseRequest |
| | | |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.interfaces import IResponse |
| | | from pyramid.interfaces import ISessionFactory |
| | | from pyramid.interfaces import IResponseFactory |
| | | |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.decorator import reify |
| | | from pyramid.response import Response |
| | | from pyramid.threadlocal import get_current_registry |
| | | from pyramid.url import resource_url |
| | | from pyramid.url import route_url |
| | | from pyramid.url import static_url |
| | |
| | | |
| | | class Response(_Response): |
| | | implements(IResponse) |
| | | |
| | | |
| | |
| | | import warnings |
| | | |
| | | from zope.interface import implements |
| | | from zope.interface import providedBy |
| | | |
| | |
| | | from pyramid.interfaces import ITraverser |
| | | from pyramid.interfaces import IView |
| | | from pyramid.interfaces import IViewClassifier |
| | | from pyramid.interfaces import IResponder |
| | | from pyramid.interfaces import IResponse |
| | | |
| | | from pyramid.events import ContextFound |
| | | from pyramid.events import NewRequest |
| | |
| | | logger = self.logger |
| | | manager = self.threadlocal_manager |
| | | request = None |
| | | responder = default_responder |
| | | threadlocals = {'registry':registry, 'request':request} |
| | | manager.push(threadlocals) |
| | | |
| | |
| | | msg = request.path_info |
| | | raise HTTPNotFound(msg) |
| | | else: |
| | | response = view_callable(context, request) |
| | | result = view_callable(context, request) |
| | | |
| | | # handle exceptions raised during root finding and view-exec |
| | | except Exception, why: |
| | |
| | | # repoze.bfg.message docs-deprecated in Pyramid 1.0 |
| | | environ['repoze.bfg.message'] = msg |
| | | |
| | | response = view_callable(why, request) |
| | | result = view_callable(why, request) |
| | | |
| | | # process the response |
| | | response = registry.queryAdapterOrSelf(result, IResponse) |
| | | if response is None: |
| | | raise ValueError( |
| | | 'Could not convert view return value "%s" into a ' |
| | | 'response' % (result,)) |
| | | |
| | | has_listeners and registry.notify(NewResponse(request,response)) |
| | | |
| | | if request.response_callbacks: |
| | | request._process_response_callbacks(response) |
| | | |
| | | responder = adapters.queryAdapter(response, IResponder) |
| | | if responder is None: |
| | | responder = default_responder(response) |
| | | |
| | | finally: |
| | | if request is not None and request.finished_callbacks: |
| | | request._process_finished_callbacks() |
| | | |
| | | return responder(request, start_response) |
| | | return response(request.environ, start_response) |
| | | |
| | | finally: |
| | | manager.pop() |
| | | |
| | | def default_responder(response): |
| | | def inner(request, start_response): |
| | | # __call__ is default 1.1 response API |
| | | call = getattr(response, '__call__', None) |
| | | if call is not None: |
| | | return call(request.environ, start_response) |
| | | # start 1.0 bw compat (use headerlist, app_iter, status) |
| | | try: |
| | | headers = response.headerlist |
| | | app_iter = response.app_iter |
| | | status = response.status |
| | | except AttributeError: |
| | | raise ValueError( |
| | | 'Non-response object returned from view ' |
| | | '(and no renderer): %r' % (response)) |
| | | start_response(status, headers) |
| | | warnings.warn( |
| | | 'As of Pyramid 1.1, an object used as a response object is ' |
| | | 'required to have a "__call__" method if an IResponder adapter is ' |
| | | 'not registered for its type. See "Deprecations" in "What\'s New ' |
| | | 'in Pyramid 1.1" within the general Pyramid documentation for ' |
| | | 'further details.', |
| | | DeprecationWarning, |
| | | 3) |
| | | return app_iter |
| | | return inner |
| | | |
| | |
| | | except ImportError: # pragma: no cover |
| | | import pickle |
| | | |
| | | from webob import Response |
| | | |
| | | import base64 |
| | | import binascii |
| | | import hmac |
| | |
| | | 'Cookie value is too long to store (%s bytes)' % |
| | | len(cookieval) |
| | | ) |
| | | if hasattr(response, 'set_cookie'): |
| | | # ``response`` is a "real" webob response |
| | | set_cookie = response.set_cookie |
| | | else: |
| | | # ``response`` is not a "real" webob response, cope |
| | | def set_cookie(*arg, **kw): |
| | | tmp_response = Response() |
| | | tmp_response.set_cookie(*arg, **kw) |
| | | response.headerlist.append( |
| | | tmp_response.headerlist[-1]) |
| | | set_cookie( |
| | | response.set_cookie( |
| | | self._cookie_name, |
| | | value=cookieval, |
| | | max_age = self._cookie_max_age, |
| | |
| | | result = config.absolute_asset_spec('templates') |
| | | self.assertEqual(result, 'pyramid.tests:templates') |
| | | |
| | | def test_setup_registry_fixed(self): |
| | | class DummyRegistry(object): |
| | | def subscribers(self, events, name): |
| | | self.events = events |
| | | return events |
| | | def registerUtility(self, *arg, **kw): |
| | | pass |
| | | def test__fix_registry_has_listeners(self): |
| | | reg = DummyRegistry() |
| | | config = self._makeOne(reg) |
| | | config._fix_registry() |
| | | self.assertEqual(reg.has_listeners, True) |
| | | |
| | | def test__fix_registry_notify(self): |
| | | reg = DummyRegistry() |
| | | config = self._makeOne(reg) |
| | | config._fix_registry() |
| | | self.assertEqual(reg.notify(1), None) |
| | | self.assertEqual(reg.events, (1,)) |
| | | |
| | | def test__fix_registry_queryAdapterOrSelf(self): |
| | | from zope.interface import Interface |
| | | class IFoo(Interface): |
| | | pass |
| | | class Foo(object): |
| | | implements(IFoo) |
| | | class Bar(object): |
| | | pass |
| | | adaptation = () |
| | | foo = Foo() |
| | | bar = Bar() |
| | | reg = DummyRegistry(adaptation) |
| | | config = self._makeOne(reg) |
| | | config._fix_registry() |
| | | self.assertTrue(reg.queryAdapterOrSelf(foo, IFoo) is foo) |
| | | self.assertTrue(reg.queryAdapterOrSelf(bar, IFoo) is adaptation) |
| | | |
| | | def test__fix_registry_registerSelfAdapter(self): |
| | | reg = DummyRegistry() |
| | | config = self._makeOne(reg) |
| | | config._fix_registry() |
| | | reg.registerSelfAdapter('required', 'provided', name='abc') |
| | | self.assertEqual(len(reg.adapters), 1) |
| | | args, kw = reg.adapters[0] |
| | | self.assertEqual(args[0]('abc'), 'abc') |
| | | self.assertEqual(kw, |
| | | {'info': u'', 'provided': 'provided', |
| | | 'required': 'required', 'name': 'abc', 'event': True}) |
| | | |
| | | def test_setup_registry_calls_fix_registry(self): |
| | | reg = DummyRegistry() |
| | | config = self._makeOne(reg) |
| | | config.add_view = lambda *arg, **kw: False |
| | | config.setup_registry() |
| | | self.assertEqual(reg.has_listeners, True) |
| | | self.assertEqual(reg.notify(1), None) |
| | | self.assertEqual(reg.events, (1,)) |
| | | |
| | | def test_setup_registry_registers_default_exceptionresponse_view(self): |
| | | from pyramid.interfaces import IExceptionResponse |
| | | from pyramid.view import default_exceptionresponse_view |
| | | class DummyRegistry(object): |
| | | def registerUtility(self, *arg, **kw): |
| | | pass |
| | | reg = DummyRegistry() |
| | | config = self._makeOne(reg) |
| | | views = [] |
| | |
| | | config.setup_registry() |
| | | self.assertEqual(views[0], ((default_exceptionresponse_view,), |
| | | {'context':IExceptionResponse})) |
| | | |
| | | def test_setup_registry_registers_default_webob_iresponse_adapter(self): |
| | | from webob import Response |
| | | from pyramid.interfaces import IResponse |
| | | config = self._makeOne() |
| | | config.setup_registry() |
| | | response = Response() |
| | | self.assertTrue( |
| | | config.registry.queryAdapter(response, IResponse) is response) |
| | | |
| | | def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self): |
| | | from zope.interface import implementedBy |
| | |
| | | def dummy_extend2(config, discrim): |
| | | config.action(discrim, None, config.registry) |
| | | |
| | | class DummyRegistry(object): |
| | | def __init__(self, adaptation=None): |
| | | self.utilities = [] |
| | | self.adapters = [] |
| | | self.adaptation = adaptation |
| | | def subscribers(self, events, name): |
| | | self.events = events |
| | | return events |
| | | def registerUtility(self, *arg, **kw): |
| | | self.utilities.append((arg, kw)) |
| | | def registerAdapter(self, *arg, **kw): |
| | | self.adapters.append((arg, kw)) |
| | | def queryAdapter(self, *arg, **kw): |
| | | return self.adaptation |
| | |
| | | |
| | | from pyramid import testing |
| | | |
| | | def hide_warnings(wrapped): |
| | | import warnings |
| | | def wrapper(*arg, **kw): |
| | | warnings.filterwarnings('ignore') |
| | | try: |
| | | wrapped(*arg, **kw) |
| | | finally: |
| | | warnings.resetwarnings() |
| | | wrapper.__name__ = wrapped.__name__ |
| | | wrapper.__doc__ = wrapped.__doc__ |
| | | return wrapper |
| | | |
| | | |
| | | class TestRouter(unittest.TestCase): |
| | | def setUp(self): |
| | | testing.setUp() |
| | |
| | | self.assertTrue("view_name: ''" in message) |
| | | self.assertTrue("subpath: []" in message) |
| | | |
| | | def test_call_view_returns_nonresponse(self): |
| | | def test_call_view_returns_non_iresponse(self): |
| | | from pyramid.interfaces import IViewClassifier |
| | | context = DummyContext() |
| | | self._registerTraverserFactory(context) |
| | |
| | | router = self._makeOne() |
| | | start_response = DummyStartResponse() |
| | | self.assertRaises(ValueError, router, environ, start_response) |
| | | |
| | | def test_call_view_returns_adapted_response(self): |
| | | from pyramid.response import Response |
| | | from pyramid.interfaces import IViewClassifier |
| | | from pyramid.interfaces import IResponse |
| | | context = DummyContext() |
| | | self._registerTraverserFactory(context) |
| | | environ = self._makeEnviron() |
| | | view = DummyView('abc') |
| | | self._registerView(view, '', IViewClassifier, None, None) |
| | | router = self._makeOne() |
| | | start_response = DummyStartResponse() |
| | | def make_response(s): |
| | | return Response(s) |
| | | router.registry.registerAdapter(make_response, (str,), IResponse) |
| | | app_iter = router(environ, start_response) |
| | | self.assertEqual(app_iter, ['abc']) |
| | | self.assertEqual(start_response.status, '200 OK') |
| | | |
| | | def test_call_view_registered_nonspecific_default_path(self): |
| | | from pyramid.interfaces import IViewClassifier |
| | |
| | | start_response = DummyStartResponse() |
| | | exc_raised(NotImplementedError, router, environ, start_response) |
| | | self.assertEqual(environ['called_back'], True) |
| | | |
| | | def test_call_with_overridden_iresponder_factory(self): |
| | | from zope.interface import Interface |
| | | from zope.interface import directlyProvides |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.interfaces import IViewClassifier |
| | | from pyramid.interfaces import IResponder |
| | | context = DummyContext() |
| | | class IFoo(Interface): |
| | | pass |
| | | directlyProvides(context, IFoo) |
| | | self._registerTraverserFactory(context, subpath=['']) |
| | | class DummyResponder(object): |
| | | def __init__(self, response): |
| | | self.response = response |
| | | def __call__(self, request, start_response): |
| | | self.response.responder_used = True |
| | | return '123' |
| | | self.registry.registerAdapter(DummyResponder, (None,), |
| | | IResponder, name='') |
| | | response = DummyResponse('200 OK') |
| | | directlyProvides(response, IFoo) |
| | | def view(context, request): |
| | | return response |
| | | environ = self._makeEnviron() |
| | | self._registerView(view, '', IViewClassifier, IRequest, Interface) |
| | | router = self._makeOne() |
| | | start_response = DummyStartResponse() |
| | | result = router(environ, start_response) |
| | | self.assertTrue(response.responder_used) |
| | | self.assertEqual(result, '123') |
| | | |
| | | def test_call_request_factory_raises(self): |
| | | # making sure finally doesnt barf when a request cannot be created |
| | |
| | | result = router(environ, start_response) |
| | | self.assertEqual(result, ["Hello, world"]) |
| | | |
| | | def test_exception_view_returns_non_response(self): |
| | | def test_exception_view_returns_non_iresponse(self): |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.interfaces import IViewClassifier |
| | | from pyramid.interfaces import IExceptionViewClassifier |
| | |
| | | start_response = DummyStartResponse() |
| | | self.assertRaises(RuntimeError, router, environ, start_response) |
| | | |
| | | class Test_default_responder(unittest.TestCase): |
| | | def _makeOne(self, response): |
| | | from pyramid.router import default_responder |
| | | return default_responder(response) |
| | | |
| | | def test_has_call(self): |
| | | response = DummyResponse() |
| | | response.app_iter = ['123'] |
| | | response.headerlist = [('a', '1')] |
| | | responder = self._makeOne(response) |
| | | request = DummyRequest({'a':'1'}) |
| | | start_response = DummyStartResponse() |
| | | app_iter = responder(request, start_response) |
| | | self.assertEqual(app_iter, response.app_iter) |
| | | self.assertEqual(start_response.status, response.status) |
| | | self.assertEqual(start_response.headers, response.headerlist) |
| | | self.assertEqual(response.environ, request.environ) |
| | | |
| | | @hide_warnings |
| | | def test_without_call_success(self): |
| | | response = DummyResponseWithoutCall() |
| | | response.app_iter = ['123'] |
| | | response.headerlist = [('a', '1')] |
| | | responder = self._makeOne(response) |
| | | request = DummyRequest({'a':'1'}) |
| | | start_response = DummyStartResponse() |
| | | app_iter = responder(request, start_response) |
| | | self.assertEqual(app_iter, response.app_iter) |
| | | self.assertEqual(start_response.status, response.status) |
| | | self.assertEqual(start_response.headers, response.headerlist) |
| | | |
| | | @hide_warnings |
| | | def test_without_call_exception(self): |
| | | response = DummyResponseWithoutCall() |
| | | del response.status |
| | | responder = self._makeOne(response) |
| | | request = DummyRequest({'a':'1'}) |
| | | start_response = DummyStartResponse() |
| | | self.assertRaises(ValueError, responder, request, start_response) |
| | | |
| | | |
| | | class DummyRequest(object): |
| | | def __init__(self, environ=None): |
| | | if environ is None: environ = {} |
| | | self.environ = environ |
| | | |
| | | class DummyContext: |
| | | pass |
| | | |
| | |
| | | self.status = status |
| | | self.headers = headers |
| | | |
| | | class DummyResponseWithoutCall: |
| | | from pyramid.interfaces import IResponse |
| | | from zope.interface import implements |
| | | |
| | | class DummyResponse(object): |
| | | implements(IResponse) |
| | | headerlist = () |
| | | app_iter = () |
| | | environ = None |
| | | def __init__(self, status='200 OK'): |
| | | self.status = status |
| | | |
| | | class DummyResponse(DummyResponseWithoutCall): |
| | | environ = None |
| | | |
| | | def __call__(self, environ, start_response): |
| | | self.environ = environ |
| | |
| | | self.assertEqual(session._set_cookie(response), True) |
| | | self.assertEqual(response.headerlist[-1][0], 'Set-Cookie') |
| | | |
| | | def test__set_cookie_other_kind_of_response(self): |
| | | request = testing.DummyRequest() |
| | | request.exception = None |
| | | session = self._makeOne(request) |
| | | session['abc'] = 'x' |
| | | response = DummyResponse() |
| | | self.assertEqual(session._set_cookie(response), True) |
| | | self.assertEqual(len(response.headerlist), 1) |
| | | |
| | | def test__set_cookie_options(self): |
| | | from pyramid.response import Response |
| | | request = testing.DummyRequest() |
| | | request.exception = None |
| | | session = self._makeOne(request, |
| | |
| | | cookie_httponly = True, |
| | | ) |
| | | session['abc'] = 'x' |
| | | response = DummyResponse() |
| | | response = Response() |
| | | self.assertEqual(session._set_cookie(response), True) |
| | | self.assertEqual(len(response.headerlist), 1) |
| | | cookieval= response.headerlist[0][1] |
| | | cookieval= response.headerlist[-1][1] |
| | | val, domain, path, secure, httponly = [x.strip() for x in |
| | | cookieval.split(';')] |
| | | self.assertTrue(val.startswith('abc=')) |
| | |
| | | secure=True) |
| | | self.assertEqual(iterable, ()) |
| | | |
| | | def test_call_view_returns_iresponse_adaptable(self): |
| | | from pyramid.response import Response |
| | | request = self._makeRequest() |
| | | context = self._makeContext() |
| | | view = make_view('123') |
| | | self._registerView(request.registry, view, 'registered') |
| | | def str_response(s): |
| | | return Response(s) |
| | | request.registry.registerAdapter(str_response, (str,), IResponse) |
| | | iterable = self._callFUT(context, request, name='registered', |
| | | secure=True) |
| | | self.assertEqual(iterable, ['123']) |
| | | |
| | | def test_call_view_registered_insecure_no_call_permissive(self): |
| | | context = self._makeContext() |
| | | request = self._makeRequest() |
| | |
| | | class DummyRequest: |
| | | exception = None |
| | | |
| | | class DummyResponse: |
| | | status = '200 OK' |
| | | from pyramid.interfaces import IResponse |
| | | from zope.interface import implements |
| | | |
| | | class DummyResponse(object): |
| | | implements(IResponse) |
| | | headerlist = () |
| | | app_iter = () |
| | | status = '200 OK' |
| | | environ = None |
| | | def __init__(self, body=None): |
| | | if body is None: |
| | | self.app_iter = () |
| | |
| | | from zope.interface import providedBy |
| | | from zope.deprecation import deprecated |
| | | |
| | | from pyramid.interfaces import IResponse |
| | | from pyramid.interfaces import IRoutesMapper |
| | | from pyramid.interfaces import IView |
| | | from pyramid.interfaces import IViewClassifier |
| | |
| | | response = render_view_to_response(context, request, name, secure) |
| | | if response is None: |
| | | return None |
| | | try: |
| | | reg = request.registry |
| | | except AttributeError: |
| | | reg = get_current_registry() |
| | | response = reg.queryAdapterOrSelf(response, IResponse) |
| | | return response.app_iter |
| | | |
| | | def render_view(context, request, name='', secure=True): |