Today I came across this and I want to answer to Ryan since he deserves more than one answer.
I strongly agree with Ryan but I notice he never tried using web2 (probably because it is not released yet) in Twisted Matrix.
... have a sane mechanism for attaching different behavior to different verbs for a single resource?
In this near-to-be-released web server each renderable resource has a renderHTTP method that is used to dispatch the request to the right renderer method after looking at the request method. For example inside the resource you can have http_GET or http_POST or http_DELETE methods and so on.
... help you use response status codes properly? (e.g. Nearly all dynamic content returns either a 200 or 500).
The result of each method call through renderHTTP must be a Response object which has the following signature:
def __init__(self, code=None, headers=None, stream=None):
I don't think I need to tell what code is, but web2 contains a module that has all the HTTP response codes with a human-readable name (one of the main problems with response codes is that they are codes, and humans can't read them).
headers is a simple dictionary of Headers:Values or directly an Headers object instance which will take care of header serialization and unserialization in an RFC compliant way.
... make dealing with transfer encodings (gzip, compress, etc.) easy?
What's the stream argument in the signature above? It is a an object that allows you to handle input and output to and from the server (James Knight, the author, would say that it's an handy implementation of the Consumer/Producer model). There are many streams already available in Web2 like MemoryStream, FileStream (when sending a file to the clients), gzipstream, deflatestream and you can write your own if you like. The stream argument is the content you need to send if the stream doesn't support the Consumer logic or, alternatively, you can pass content to the stream using the write() method if it supports Consumer logic.
... make dealing with media types easy?
MediaTypes are handled correctly with the MimeType object togheter with the corresponding serializer (which is handled transparently by web2, but you can provide your own).
... provide facilities for implementing a smart caching strategy for dynamic content? (proper use of If-Modified-Since, Expires, Cache-Control, etc.)
It's not completely clear to me what this means. Caching dynamic content is very hard and the framework should never step-in IMHO. That is a completely user-driven feature but web2 allows you to put your headers in the response object, hence I believe this satisfies this point.
What are my conclusions? Just give web2 a try. Come in #twisted.web on freenode to talk about future web2 and Nevow development (Nevow gave a lot of code to web2 resource handling mechanisms, but James Knight, web2 author, changed the original code enough to allow all the flexibility of the new model I just described in this post).
As a Nevow developer I must say that I'm looking forward to the day when we move from twisted.web to twisted.web2 to enable all this new stuff, which I also need to handle from my software.
To close everything: web2 already supports wsgi.