Why does WSGI have to use start_response and return an iterator?

cgi, django, python, web, wsgi

Solution

The simple answer is: It has to be this way because WSGI specifies it this way. ;-)

`start_response()` is passed in both examples, in the first example it's just ”bundled” with the `request` object and WSGI separates the environment variables from the callable to start a response.

Returning an iterable makes it easier to produce the response in a lazy way and to chain multiple middlewares without the need to hand over the whole content at once from one middleware to the next. The generator function isn't the simplest solution by the way, because the return value just have to be iterable, not an iterator itself or even a generator. So this would be the smallest example of an WSGI app:

def app(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return ['Hello world!\n']

I think this looks actually simpler and easier than the non-WSGI example.

Problem

The non-WSGI way: ``` def my_view(request): request.start_response('200 OK') request.send_header('Content-Type', 'text/plain') request.end_headers() request.write('Hello World!') request.write('Goodbye World!') request.end() ``` The WSGI way: ``` def my_view(environ, start_response): def generate(): yield 'Hello World!' yield 'Goodbye World!' start_response('200 OK', [('Content-Type', 'text/plain')]) return generate() ``` The codes are from this blog, though I didn't quite understand it.. As can be seen above, the non-WSGI looks much easier. And the WSGI looks confusing.. Why does the `start_reponse` have to be passed in `my_view`? Why does the `my_view` have to return an iterator? And where is the `request` object in WSGI way? Does anyone have ideas about this?

Original source