Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalresistor committed Nov 21, 2016
1 parent d3ab6fc commit 366ac28
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 110 deletions.
2 changes: 2 additions & 0 deletions docs/api/response.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ Response
.. automodule:: webob.response
.. autoclass:: webob.response.Response
:members:
.. autoclass:: webob.response.ResponseBodyFile
:members:
.. autoclass:: webob.response.AppIterRange
:members:
134 changes: 87 additions & 47 deletions docs/whatsnew-1.7.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,40 @@ Compatibility
Backwards Incompatibility
~~~~~~~~~~~~~~~~~~~~~~~~~

- Response.set_cookie no longer accepts a key argument. This was deprecated in
WebOb 1.5 and as mentioned in the deprecation, is being removed in 1.7
- :class:`~webob.response.Response` no longer treats ``application/json`` as a
special case that may also be treated as text. This means the following may
no longer be used:

.. code-block:: python

res = Response(json.dumps({}), content_type='application/json')

Since ``application/json`` does not have a ``charset``, this will now raise
an error.

Replacements are:

.. code-block:: python

res = Response(json_body={})

This will create a new :class:`~webob.response.Response` that automatically
sets up the the Content-Type and converts the dictionary to a JSON object
internally.

If you want WebOb to the encoding but do the conversion to JSON yourself, the
following would also work:

.. code-block:: python

res = Response(text=json.dumps({}), content_type='application/json')

This uses :attr:`~webob.response.Response.default_body_encoding` to encode
the text.

- :func:`Response.set_cookie <webob.response.Response.set_cookie>` no longer
accepts a key argument. This was deprecated in WebOb 1.5 and as mentioned in
the deprecation, is being removed in 1.7

Use:

Expand All @@ -35,14 +67,16 @@ Backwards Incompatibility
res = Response()
res.set_cookie(key='cookie_name', value='val')

- Response `__init__` will no longer set the default Content-Type, nor
Content-Length on Responses that don't have a body. This allows WebOb to
return proper responses for things like `Response(status='204 No Content')`.
- :func:`Response.__init__ <webob.response.Response>` will no longer
set the default Content-Type, nor Content-Length on Responses that don't have
a body. This allows WebOb to return proper responses for things like
`Response(status='204 No Content')`.

- Response.text will no longer raise if the Content-Type does not have a
charset, it will fall back to using the new default_body_encoding. To get the
old behaviour back please sub-class Response and set default_body_encoding to
None. See https://github.com/Pylons/webob/pull/287
- :attr:`Response.text <webob.response.Response.text>` will no longer raise if
the Content-Type does not have a charset, it will fall back to using the new
default_body_encoding. To get the old behaviour back please sub-class
Response and set default_body_encoding to None. See
https://github.com/Pylons/webob/pull/287

An example of a Response class that has the old behaviour:

Expand All @@ -63,8 +97,9 @@ Backwards Incompatibility
Feature
~~~~~~~

- Response has a new default_body_encoding which may be used to allow
getting/setting Response.text when a Content-Type has no charset. See
- :class:`~webob.response.Response` has a new ``default_body_encoding`` which
may be used to allow getting/setting :attr:`Response.text
<webob.response.Response.text>` when a Content-Type has no charset. See
https://github.com/Pylons/webob/pull/287

.. code-block:: python
Expand All @@ -79,16 +114,17 @@ Feature
res.text == 'A valid latin-1 string'


- webob.Request with any HTTP method is now allowed to have a body. This allows
DELETE to have a request body for passing extra information. See
https://github.com/Pylons/webob/pull/283 and
- :class:`~webob.request.Request` with any HTTP method is now allowed to have a
body. This allows DELETE to have a request body for passing extra
information. See https://github.com/Pylons/webob/pull/283 and
https://github.com/Pylons/webob/pull/274

- Add `tell()` to `ResponseBodyFile` so that it may be used for example for
ZipFile support. See https://github.com/Pylons/webob/pull/117
- Add :func:`~webob.response.ResponseBodyFile.tell` to
:class:`~webob.response.ResponseBodyFile` so that it may be used for example
for zipfile support. See https://github.com/Pylons/webob/pull/117

- Allow the return from `wsgify.middleware` to be used as a decorator. See
https://github.com/Pylons/webob/pull/228
- Allow the return from :func:`wsgify.middleware <webob.dec.wsgify.middleware>` to
be used as a decorator. See https://github.com/Pylons/webob/pull/228

.. code-block:: python

Expand All @@ -106,31 +142,34 @@ Feature
Bugfix
~~~~~~

- Fixup cgi.FieldStorage on Python 3.x to work-around issue reported in Python
bug report 27777 and 24764. This is currently applied for Python versions
less than 3.7. See https://github.com/Pylons/webob/pull/294
- Fixup :class:`cgi.FieldStorage` on Python 3.x to work-around issue reported
in Python bug report 27777 and 24764. This is currently applied for Python
versions less than 3.7. See https://github.com/Pylons/webob/pull/294

- Response.set_cookie now accepts datetime objects for the expire kwarg and
will correctly convert them to UTC with no tzinfo for use in calculating the
max_age. See https://github.com/Pylons/webob/issues/254 and
- :func:`Response.set_cookie <webob.response.Response.set_cookie>` now accepts
:class:`~datetime.datetime` objects for the ``expires`` kwarg and will
correctly convert them to UTC with no ``tzinfo`` for use in calculating the
``max_age``. See https://github.com/Pylons/webob/issues/254 and
https://github.com/Pylons/webob/pull/292

- Fixes request.PATH_SAFE to contain all of the path safe characters according
to RFC3986. See https://github.com/Pylons/webob/pull/291
- Fixes :attr:`request.PATH_SAFE <webob.request.PATH_SAFE>` to contain all of
the path safe characters according to RFC3986. See
https://github.com/Pylons/webob/pull/291

- WebOb's exceptions will lazily read underlying variables when inserted into
templates to avoid expensive computations/crashes when inserting into the
template. This had a bad performance regression on Py27 because of the way
the lazified class was created and returned. See
https://github.com/Pylons/webob/pull/284

- `wsgify.__call__` raised a `TypeError` with an unhelpful message, it will now
return the `repr` for the wrapped function:
https://github.com/Pylons/webob/issues/119
- :func:`wsgify.__call__ <webob.dec.wsgify.__call__>` raised a ``TypeError``
with an unhelpful message, it will now return the `repr` for the wrapped
function: https://github.com/Pylons/webob/issues/119

- Response.content_type removes the charset content_type parameters unless the
new content_type is a text like type that has a charset parameter.
See https://github.com/Pylons/webob/pull/261 and
- :attr:`Response.content_type <webob.response.Response.content_type>` removes
the charset content-type parameter unless the new content_type is a text
like type that has a charset parameter. See
https://github.com/Pylons/webob/pull/261 and
https://github.com/Pylons/webob/issues/130

Future versions of WebOb will remove all Content-Type parameters, and the
Expand All @@ -155,31 +194,32 @@ Bugfix

assert res.headers['Content-Type'] == 'application/unknown; charset=UTF-8'

- Response.json's json.dumps/loads are now always UTF-8. It no longer tries to
use the charset.
- :attr:`Response.json <webob.response.Response.json>`'s json.dumps/loads are
now always UTF-8. It no longer tries to use the charset.

- The Response `__init__` will by default no longer set the Content-Type to the
default if a headerlist is provided. This fixes issues whereby
`Request.get_response()` would return a Response that didn't match the actual
response.
See https://github.com/Pylons/webob/pull/261 and
- The :class:`~webob.response.Response` will by default no longer set the
Content-Type to the default if a headerlist is provided. This fixes issues
whereby `Request.get_response()` would return a Response that didn't match
the actual response. See https://github.com/Pylons/webob/pull/261 and
https://github.com/Pylons/webob/issues/205

- Cleans up the remainder of the issues with the updated WebOb exceptions that
were taught to return JSON in version 1.6. See
https://github.com/Pylons/webob/issues/237 and
https://github.com/Pylons/webob/issues/236

- Response.from_file now parses the status line correctly when the status line
contains an HTTP with version, as well as a status text that contains
multiple white spaces (e.g HTTP/1.1 404 Not Found). See
https://github.com/Pylons/webob/issues/250
- :func:`Response.from_file <webob.response.Response.from_file>` now parses the
status line correctly when the status line contains an HTTP with version, as
well as a status text that contains multiple white spaces (e.g HTTP/1.1 404
Not Found). See https://github.com/Pylons/webob/issues/250

- Response now has a new property named `has_body` that may be used to
interrogate the Response to find out if `Response.body` is or isn't set.
- :class:`~webob.response.Response` now has a new property named
:attr:`~webob.response.Response.has_body` that may be used to interrogate the
Response to find out if the :attr:`~webob.response.Response.body` is or isn't
set.

This is used in the exception handling code so that if you use a WebOb HTTP
Exception and pass a generator to `app_iter` WebOb won't attempt to read the
whole thing and instead allows it to be returned to the WSGI server. See
Exception and pass a generator to ``app_iter`` WebOb won't attempt to read
the whole thing and instead allows it to be returned to the WSGI server. See
https://github.com/Pylons/webob/pull/259

136 changes: 73 additions & 63 deletions webob/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,91 +74,92 @@

class Response(object):
"""
Represents a WSGI response.
Represents a WSGI response.
If no arguments are passed, creates a :class:`~Response` that uses a
variety of defaults. The defaults may be changed by sub-classing the
:class:`~Response`. See the :ref:`sub-classing notes
<response_subclassing_notes>`.
If no arguments are passed, creates a :class:`~Response` that uses a
variety of defaults. The defaults may be changed by sub-classing the
:class:`~Response`. See the :ref:`sub-classing notes
<response_subclassing_notes>`.
:cvar ~Response.body: If ``body`` is a ``text_type``, then it will be
encoded using either ``charset`` when provided or
``default_encoding`` when ``charset`` is not provided. This
argument is mutually exclusive with ``app_iter``.
:cvar ~Response.body: If ``body`` is a ``text_type``, then it will be
encoded using either ``charset`` when provided or ``default_encoding``
when ``charset`` is not provided if the ``content_type`` allows for a
``charset``. This argument is mutually exclusive with ``app_iter``.
:vartype ~Response.body: bytes or text_type
:vartype ~Response.body: bytes or text_type
:cvar ~Response.status: Either an :class:`int` or a string that is
an integer followed by the status text. If it is an integer, it
will be converted to a proper status that also includes the status
text. Any existing status text will be kept. Non-standard values
are allowed.
:cvar ~Response.status: Either an :class:`int` or a string that is
an integer followed by the status text. If it is an integer, it will be
converted to a proper status that also includes the status text. Any
existing status text will be kept. Non-standard values are allowed.
:vartype ~Response.status: int or str
:vartype ~Response.status: int or str
:cvar list ~Response.headerlist: A list of HTTP headers for the response.
:cvar ~Response.headerlist: A list of HTTP headers for the response.
:cvar ~Response.app_iter: An iterator that is used as the body of the
response. Should conform to the WSGI requirements and should
provide bytes. This argument is mutually exclusive with ``body``.
:vartype ~Response.headerlist: list
:vartype ~Response.app_iter: iterable
:cvar ~Response.app_iter: An iterator that is used as the body of the
response. Should conform to the WSGI requirements and should provide
bytes. This argument is mutually exclusive with ``body``.
:cvar ~Response.content_type: Sets the ``Content-Type`` header. If no
``content_type`` is provided, and there is no ``headerlist``, the
``default_content_type`` will be automatically set. If
``headerlist`` is provided then this value is ignored.
:vartype ~Response.app_iter: iterable
:vartype ~Response.content_type: str or None
:cvar ~Response.content_type: Sets the ``Content-Type`` header. If no
``content_type`` is provided, and there is no ``headerlist``, the
``default_content_type`` will be automatically set. If ``headerlist``
is provided then this value is ignored.
:cvar conditional_response: Used to change the behavior of the
:class:`~Response` to check the original request for conditional
response headers. See :meth:`~Response.conditional_response_app`
for more information.
:vartype ~Response.content_type: str or None
:vartype conditional_response: bool
:cvar conditional_response: Used to change the behavior of the
:class:`~Response` to check the original request for conditional
response headers. See :meth:`~Response.conditional_response_app` for
more information.
:cvar ~Response.charset: Adds a ``charset`` ``Content-Type`` parameter. If no
``charset`` is provided and the ``Content-Type`` is text, then the
``default_charset`` will automatically be added. Currently the
only ``Content-Type``'s that allow for a ``charset`` are defined to
be ``text/*``, ``application/xml``, and ``*/*+xml``. Any other
``Content-Type``'s will not have a ``charset`` added. If a
``headerlist`` is provided this value is ignored.
:vartype conditional_response: bool
:vartype ~Response.charset: str or None
:cvar ~Response.charset: Adds a ``charset`` ``Content-Type`` parameter. If
no ``charset`` is provided and the ``Content-Type`` is text, then the
``default_charset`` will automatically be added. Currently the only
``Content-Type``'s that allow for a ``charset`` are defined to be
``text/*``, ``application/xml``, and ``*/*+xml``. Any other
``Content-Type``'s will not have a ``charset`` added. If a
``headerlist`` is provided this value is ignored.
All other response attributes may be set on the response by providing
them as keyword arguments. A :exc:`TypeError` will be raised for any
unexpected keywords.
:vartype ~Response.charset: str or None
.. _response_subclassing_notes:
All other response attributes may be set on the response by providing them
as keyword arguments. A :exc:`TypeError` will be raised for any unexpected
keywords.
**Sub-classing notes:**
.. _response_subclassing_notes:
* The ``default_content_type`` is used as the default for the
``Content-Type`` header that is returned on the response. It is
``text/html``.
**Sub-classing notes:**
* The ``default_charset`` is used as the default character set to
return on the ``Content-Type`` header, if the ``Content-Type`` allows
for a ``charset`` parameter. Currently the only ``Content-Type``'s
that allow for a ``charset`` are defined to be: ``text/*``,
``application/xml``, and ``*/*+xml``. Any other ``Content-Type``'s
will not have a ``charset`` added.
* The ``default_content_type`` is used as the default for the
``Content-Type`` header that is returned on the response. It is
``text/html``.
* The ``unicode_errors`` is set to ``strict``, and access on a
:attr:`~Response.text` will raise an error if it fails to decode the
:attr:`~Response.body`.
* The ``default_charset`` is used as the default character set to return on
the ``Content-Type`` header, if the ``Content-Type`` allows for a
``charset`` parameter. Currently the only ``Content-Type``'s that allow
for a ``charset`` are defined to be: ``text/*``, ``application/xml``, and
``*/*+xml``. Any other ``Content-Type``'s will not have a ``charset``
added.
* ``default_conditional_response`` is set to False. This flag may be
set to True so that all ``Response`` objects will attempt to check
the original request for conditional response headers. See
:meth:`~Response.conditional_response_app` for more information.
* The ``unicode_errors`` is set to ``strict``, and access on a
:attr:`~Response.text` will raise an error if it fails to decode the
:attr:`~Response.body`.
* ``default_body_encoding`` is set to 'UTF-8' by default, it exists to
allow users to get/set the Response object using .text, even if no
charset has been set for the Content-Type.
* ``default_conditional_response`` is set to False. This flag may be set to
True so that all ``Response`` objects will attempt to check the original
request for conditional response headers. See
:meth:`~Response.conditional_response_app` for more information.
* ``default_body_encoding`` is set to 'UTF-8' by default, it exists to
allow users to get/set the Response object using .text, even if no
charset has been set for the Content-Type.
"""

default_content_type = 'text/html'
Expand Down Expand Up @@ -1412,6 +1413,9 @@ class ResponseBodyFile(object):
closed = False

def __init__(self, response):
"""
Represents a :class:`~Response` as a file like object.
"""
self.response = response
self.write = response.write

Expand All @@ -1424,6 +1428,9 @@ def __repr__(self):
)

def writelines(self, seq):
"""
Write a sequence of lines to the response
"""
for item in seq:
self.write(item)

Expand All @@ -1434,6 +1441,9 @@ def flush(self):
pass

def tell(self):
"""
Provide the current location where we are going to start writing
"""
if self.response.app_iter is None: # pragma: no cover
return 0

Expand Down

0 comments on commit 366ac28

Please sign in to comment.