NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1911 most downloaded on PyPI
WSGI request and response object
Last release 1 months ago
02 Aug 2026
Ships unpredictably
gaps range from 4 weeks to 3.5 years
Most releases are documented
notes for 49 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
19 years old
75 releases · first in 2007
Resolve deprecation warnings for parse_qsl on Python 2.6 and newer.
Moved repository from svn location to https://bitbucket.org/ianb/webob/wiki/Home
Arguments to Accept.best_match must be specific types, not wildcards. The server should know a list of specic types it can offer and use best_match to select a specific one.
With req.accept.best_match([types]) prefer the first type in the list (previously it preferred later types).
Also, make sure that if the user-agent accepts multiple types and there are multiple matches to the types that the application offers, req.accept.best_match([..]) returns the most specific match. So if the server can satisfy either image/* or text/plain types, the latter will be picked independent from the order the accepted or offered types are listed (given they have the same quality rating).
Fix Range, Content-Range and AppIter support all of which were broken in many ways, incorrectly parsing ranges, reporting incorrect content-ranges, failing to generate the correct body to satisfy the range from app_iter etc.
Fix assumption that presense of a seek method means that the stream is seekable.
Add ubody alias for Response.unicode_body
Add Unicode versions of Request.script_name and path_info: uscript_name and upath_info.
Split __init__.py into four modules: request, response, descriptors and datetime_utils.
Fix Response.body access resetting Content-Length to zero for HEAD responses.
Support passing Unicode bodies to WSGIHTTPException constructors.
Make bool(req.accept) return False for requests with missing Accept header.
Add HTTP version to Request.__str__ output.
Resolve deprecation warnings for parse_qsl on Python 2.6 and newer.
Fix Response.md5_etag setting Content-MD5 in incorrect format.
Add Request.authorization property for Authorization header.
Make sure ETag value is always quoted (required by RFC)
Moved most Request behavior into a new class named BaseRequest. The Request class is now a superclass for BaseRequest and a simple mixin which manages environ['webob.adhoc_attrs'] when __setitem__, __delitem__ and __getitem__ are called. This allows framework developers who do not want the environ['webob.adhoc_attrs'] mutation behavior from __setattr__. (chrism)
Added response attribute response.content_disposition for its associated header.
Changed how charset is determined on webob.Request objects. Now the charset parameter is read on the Content-Type header, if it is present. Otherwise a default_charset parameter is read, or the charset argument to the Request constructor. This is more similar to how webob.Response handles the charset.
Made the case of the Content-Type header consistent (note: this might break some doctests).
Make req.GET settable, such that req.environ['QUERY_STRING'] is updated.
Fix problem with req.POST causing a re-parse of the body when you instantiate multiple Request objects over the same environ (e.g., when using middleware that looks at req.POST).
Recreate the request body properly when a POST includes file uploads.
When req.POST is updated, the generated body will include the new values.
Added a POST parameter to webob.Request.blank; when given this will create a request body for the POST parameters (list of two-tuples or dictionary-like object). Note: this does not handle unicode or file uploads.
Added method webob.Response.merge_cookies, which takes the Set-Cookie headers from a Response, and merges them with another response or WSGI application. (This is useful for flash messages.)
Fix a problem with creating exceptions like webob.exc.HTTPNotFound(body='<notfound/>', content_type='application/xml') (i.e., non-HTML exceptions).
When a Location header is not absolute in a Response, it will be made absolute when the Response is called as a WSGI application. This makes the response less bound to a specific request.
Added webob.dec, a decorator for making WSGI applications from functions with the signature resp = app(req).
One column per quarter.
Fixed Response.__init__, which for some content types would raise an exception.
Fixed Response.__init__, which for some content types would raise an exception.
The req.body property will not recreate a StringIO object unnecessarily when rereading the body.
Removed environ_getter from webob.Request. This largely-unused option allowed a Request object to be instantiated with a dynamic underlying environ. S
Removed environ_getter from webob.Request. This largely-unused option allowed a Request object to be instantiated with a dynamic underlying environ. Since it wasn't used much, and might have been ill-advised from the beginning, and affected performance, it has been removed (from Chris McDonough).
Speed ups for webob.Response.__init__ and webob.Request.__init__
Fix defaulting of CONTENT_TYPE instead of CONTENT_LENGTH to 0 in Request.str_POST.
Added webob.Response.copy
Fix Request.blank('/').copy() raising an exception.
Fix Request.blank('/').copy() raising an exception.
Fix a potential memory leak with HEAD requests and 304 responses.
Make webob.html_escape respect the .__html__() magic method, which allows you to use HTML in webob.exc.HTTPException instances.
Handle unicode values for resp.location.
Allow arbitrary keyword arguments to exc.HTTP* (the same keywords you can send to webob.Response).
Allow setting webob.Response.cache_expires (usually it is called as a method). This is primarily to allow Response(cache_expires=True).
Quiet Python 2.6 deprecation warnings.
Quiet Python 2.6 deprecation warnings.
Added an attribute unicode_errors to webob.Response -- if set to something like unicode_errors='replace' it will decode resp.body appropriately. The default is strict (which was the former un-overridable behavior).
Make sure that if changing the body the Content-MD5 header is removed. (Otherwise a lot of middleware would accidentally corrupt responses).
Make sure that if changing the body the Content-MD5 header is removed. (Otherwise a lot of middleware would accidentally corrupt responses).
Fixed Response.encode_content('identity') case (was a no-op even for encoded bodies).
Fixed Request.remove_conditional_headers that was removing If-Match header instead of If-None-Match.
Fixed resp.set_cookie(max_age=timedelta(...))
request.POST now supports PUT requests with the appropriate Content-Type.
Add more arguments to Request.remove_conditional_headers for more fine-grained control: remove_encoding, remove_range, remove_match, remove_modified.
Add more arguments to Request.remove_conditional_headers for more fine-grained control: remove_encoding, remove_range, remove_match, remove_modified. All of them are True by default.
Add an set_content_md5 argument to Response.md5_etag that calculates and sets Content-MD5 reponse header from current body.
Change formatting of cookie expires, to use the more traditional format Wed, 5-May-2001 15:34:10 GMT (dashes instead of spaces). Browsers should deal with either format, but some other code expects dashes.
Added in sorted function for backward compatibility with Python 2.3.
Allow keyword arguments to webob.Request, which assign attributes (possibly overwriting values in the environment).
Added methods webob.Request.make_body_seekable and webob.Request.copy_body, which make it easier to share a request body among different consuming applications, doing something like req.make_body_seekable(); req.body_file.seek(0)
request.params.copy() now returns a writable MultiDict (before it returned an unwritable object).
request.params.copy() now returns a writable MultiDict (before
it returned an unwritable object).
There were several things broken with UnicodeMultiDict when
decode_param_names is turned on (when the dictionary keys are
unicode).
You can pass keyword arguments to Request.blank() that will be
used to construct Request (e.g., Request.blank('/', decode_param_names=True)).
If you set headers like response.etag to a unicode value, they
will be encoded as ISO-8859-1 (however, they will remain encoded,
and response.etag will not be a unicode value).
When parsing, interpret times with no timezone as UTC (previously they would be interpreted as local time).
Set the Expires property on cookies when using
response.set_cookie(). This is inherited from max_age.
Support Unicode cookie values
Backward Incompatible Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Added req.urlarg, which represents positional arguments in
environ['wsgiorg.routing_args'].
For Python 2.4, added attribute get/set proxies on exception objects
from, for example, webob.exc.HTTPNotFound().exception, so that
they act more like normal response objects (despite not being
new-style classes or webob.Response objects). In Python 2.5 the
exceptions are webob.Response objects.
Backward Incompatible Changes
* The ``Response`` constructor has changed: it is now ``Response([body],
[status], ...)`` (before it was ``Response([status], [body], ...)``).
Body may be str or unicode.
* The ``Response`` class defaults to ``text/html`` for the
Content-Type, and ``utf8`` for the charset (charset is only set on
``text/*`` and ``application/*+xml`` responses).
Bugfixes and Small Changes
~~~~~~~~~~~~~~~~~~~~~~~~~~
* Use ``BaseCookie`` instead of ``SimpleCookie`` for parsing cookies.
* Added ``resp.write(text)`` method, which is equivalent to
``resp.body += text`` or ``resp.unicode_body += text``, depending on
the type of ``text``.
* The ``decode_param_names`` argument (used like
``Request(decode_param_names=True)``) was being ignored.
* Unicode decoding of file uploads and file upload filenames were
causing errors when decoding non-file-upload fields (both fixes from
Ryan Barrett).
Added response methods resp.encode_content() and resp.decode_content() to gzip or ungzip content.
Added response methods resp.encode_content() and
resp.decode_content() to gzip or ungzip content.
Response(status=404) now works (before you would have to use
status="404 Not Found").
Bugfix (typo) with reusing POST body.
Added 226 IM Used response status.
Backport of string.Template included for Python 2.3
compatibility.
__setattr__ would keep Request subclasses from having properly settable environ proxies (like req.path_info).
__setattr__ would keep Request subclasses from having
properly settable environ proxies (like req.path_info).request.POST was giving FieldStorage objects for *every* attribute, not just file uploads. This is fixed now.
request.POST was giving FieldStorage objects for every
attribute, not just file uploads. This is fixed now.
Added request attributes req.server_name and req.server_port
for the environ keys SERVER_NAME and SERVER_PORT.
Avoid exceptions in req.content_length, even if
environ['CONTENT_LENGTH'] is somehow invalid.
Deprecate req.postvars and req.queryvars, instead using the sole names req.GET and req.POST (also req.str_GET and req.str_POST). The old names give a…
Python 2.3 compatibility: backport of reversed(seq)
Made separate .exception attribute on webob.exc objects,
since new-style classes can't be raised as exceptions.
Deprecate req.postvars and req.queryvars, instead using the
sole names req.GET and req.POST (also req.str_GET and
req.str_POST). The old names give a warning; will give an error
in next release, and be completely gone in the following release.
req.user_agent is now just a simple string (parsing the
User-Agent header was just too volatile, and required too much
knowledge about current browsers). Similarly,
req.referer_search_query() is gone.
Added parameters version and comment to
Response.set_cookie(), per William Dode's suggestion.
Was accidentally consuming file uploads, instead of putting the
FieldStorage object directly in the parameters.
Added res.set_cookie(..., httponly=True) to set the HttpOnly attribute on the cookie, which keeps Javascript from reading the cookie.
Added res.set_cookie(..., httponly=True) to set the HttpOnly
attribute on the cookie, which keeps Javascript from reading the
cookie.
Added some WebDAV-related responses to webob.exc
Set default Last-Modified when using response.cache_expire()
(fixes issue with Opera)
Generally fix .cache_control
First release. Nothing is new, or everything is new, depending on how you think about it.
First release. Nothing is new, or everything is new, depending on how you think about it.
Your coding agent can read these notes before it upgrades. Set up the MCP server →