What’s New in WebOb 1.7
Compatibility
WebOb is no longer supported on Python 2.6 and PyPy3. PyPy3 support will be re-introduced as soon as it supports a Python version higher than 3.2 and pip fully supports the platform again.
If you would like Python 2.6 support, please pin to WebOb 1.6, which still has Python 2.6 support.
Backwards Incompatibility
Response.content_type removes all existing Content-Type parameters, and if the new Content-Type is “texty” it adds a new charset (unless already provided) using the
default_charset
, to emulate the old behaviour you may use the following:res = Response(content_type='text/html', charset='UTF-8')
assert res.content_type == 'text/html'
assert res.charset == 'UTF-8'
params = res.content_type_params
# Change the Content-Type
res.content_type = 'application/unknown'
assert res.content_type == 'application/unknown'
assert res.charset == None
# This will add the ``charset=UTF-8`` parameter to the Content-Type
res.content_type_params = params
assert res.headers['Content-Type'] == 'application/unknown; charset=UTF-8'
See https://github.com/Pylons/webob/pull/301 for more information.
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:res = Response(json.dumps({}), content_type='application/json')
Since
application/json
does not have acharset
, this will now raise an error.Replacements are:
res = Response(json_body={})
This will create a new 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:
res = Response(text=json.dumps({}), content_type='application/json')
This uses
default_body_encoding
to encode the text.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:
res = Response()
res.set_cookie(name='cookie_name', value='val')
# or
res.set_cookie('cookie_name', 'val')
Instead of:
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’).
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:
class MyResponse(Response):
default_body_encoding = None
res = MyResponse(content_type='application/json')
# This will raise as application/json doesn't have a charset
res.text = 'sometext'
WebOb no longer supports Chunked Encoding, this means that if you are using WebOb and need Chunked Encoding you will be required to have a proxy that unchunks the request for you. Please read https://github.com/Pylons/webob/issues/279 for more background.
This changes the behaviour of
request.is_body_readable
, it will no longer assume that a request has a body just because it is a particular HTTP verb. This change also allows any HTTP verb to be able to contain a body, which allows for example a HTTP body on DELETE or even GET.
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 https://github.com/Pylons/webob/pull/287res = Response()
res.default_body_encoding = 'latin1'
res.text = 'Will be encoded as latin1 and .body will be set'
res = Response()
res.default_body_encoding = 'latin1'
res.body = b'A valid latin-1 string'
res.text == 'A valid latin-1 string'
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
Allow the return from wsgify.middleware to be used as a decorator. See https://github.com/Pylons/webob/pull/228
@wsgify.middleware
def restrict_ip(req, app, ips):
if req.remote_addr not in ips:
raise webob.exc.HTTPForbidden('Bad IP: %s' % req.remote_addr)
return app
@restrict_ip(ips=['127.0.0.1'])
@wsgify
def app(req):
return 'hi'
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/294Response.set_cookie now accepts datetime objects for the
expires
kwarg and will correctly convert them to UTC with notzinfo
for use in calculating themax_age
. See https://github.com/Pylons/webob/issues/254 and https://github.com/Pylons/webob/pull/292Fixes
request.PATH_SAFE
to contain all of the path safe characters according to RFC3986. See https://github.com/Pylons/webob/pull/291WebOb’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 aTypeError
with an unhelpful message, it will now return the repr for the wrapped function: https://github.com/Pylons/webob/issues/119Response.json‘s json.dumps/loads are now always UTF-8. It no longer tries to use the charset.
The 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
Response now has a new property named has_body that may be used to interrogate the Response to find out if the 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 https://github.com/Pylons/webob/pull/259