I'm trying to get the 'hello world' of streaming responses working for Django (1.2). I figured out how to use a generator and the yield
function. But the response still not streaming. I suspect there's a middleware that's mucking with it -- maybe ETAG calculator? But I'm not sure how to disable it. Can somebody please help?
Here's the "hello world" of streaming that I have so far:
def stream_response(request): resp = HttpResponse( stream_response_generator()) return resp def stream_response_generator(): for x in range(1,11): yield "%s\n" % x # Returns a chunk of the response to the browser time.sleep(1)
A StreamingHttpResponse , on the other hand, is a response whose body is sent to the client in multiple pieces, or “chunks.” Here's a short example of using StreamingHttpResponse : def hello(): yield 'Hello,' yield 'there!' def my_view(request): # NOTE: No Content-Length header! return StreamingHttpResponse(hello)
Django uses request and response objects to pass state through the system. When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function.
Django's HttpResponse class is used to define an HTTP response. It comes from the django. http module, and it contains a set of predefined attributes and methods you can use to return the appropriate response to the client. You will usually use this class inside a view function, for example, in views.py .
You can disable the ETAG middleware using the condition decorator. That will get your response to stream back over HTTP. You can confirm this with a command-line tool like curl
. But it probably won't be enough to get your browser to show the response as it streams. To encourage the browser to show the response as it streams, you can push a bunch of whitespace down the pipe to force its buffers to fill. Example follows:
from django.views.decorators.http import condition @condition(etag_func=None) def stream_response(request): resp = HttpResponse( stream_response_generator(), content_type='text/html') return resp def stream_response_generator(): yield "<html><body>\n" for x in range(1,11): yield "<div>%s</div>\n" % x yield " " * 1024 # Encourage browser to render incrementally time.sleep(1) yield "</body></html>\n"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With