I'm having a problem with Django response class StreamingHttpResponse. When I return a generator as response using StreamingHttpResponse and make a request I excepted to retrieve each data block one by one, instead of that i retrieve the full data at once when the generator loop has finished.
My Django View:
def gen_message(msg):
return '\ndata: {}\n\n'.format(msg)
def iterator():
for i in range(100):
yield gen_message('iteration ' str(i))
print(i)
time.sleep(0.1)
class test_stream(APIView):
def post(self, request):
stream = iterator()
response = StreamingHttpResponse(stream, status=200, content_type='text/event-stream')
response['Cache-Control'] = 'no-cache'
return response
And I make the request like that:
r = requests.post('https://******/test_stream/', stream=True)
for line in r.iter_lines():
if line:
decoded_line = line.decode('utf-8')
print(decoded_line)
When I see the output of the Django server I can see the print every 0.1 seconds. But the response in the second code only shows when the for loop is finished. Am I misunderstanding the StreamingHttpResponse class or the request class or is there another problem? Thanks:)
CodePudding user response:
The problem is the line
stream = iterator()
Here, you're calling the function iterator
, and the variable stream
will contain the return value.
Instead, try:
stream = iterator
because you want to pass the iterator function itself as the first argument to StreamingHttpResponse.
(or just do response = StreamingHttpResponse(iterator, status=200, content_type='text/event-stream')
)
CodePudding user response:
You will need to ensure that there is no middleware or webserver in between that first "buffers" the response.
In Nginx that is possible if the proxy_buffering
setting is turned on. You will thus need to disable this with:
proxy_buffering off;