Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stream an HttpResponse with Django

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) 
like image 276
muudscope Avatar asked May 27 '10 16:05

muudscope


People also ask

What is StreamingHttpResponse?

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)

How to use requests in Django?

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.

What is from Django HTTP import HttpResponse?

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 .


1 Answers

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" 
like image 113
Leopd Avatar answered Sep 23 '22 13:09

Leopd