[Welcome] [TitleIndex] [WordIndex

Problem

Usually the response from a handler function is returned as a string, which means that the whole response has to be constructed in memory. If you want to return a very large file, however, this will consume a lot of memory.

Solution

Instead of returning a string, a handler can also return an instance of the quixote.http_response.Stream class, wrapping it around an iterable that returns chunks of the large object.

from quixote.http_response import Stream

def generate_data ():
    "Generate a large amount of data"
    while (...):
        yield chunk

def data_output (request):
    # Set the MIME type to whatever is suitable
    request.response_set_content_type('application/octet-stream')
    return Stream(generate_data())

For the common case of streaming output from a file, the quixote.util modules contains a FileStream class that takes a file object:

def large_file (request):
    filename = "/usr/share/qxapp/large-file.pdf'
    size = os.path.getsize(filename)
    request.response.set_content_type('application/pdf')
    input = open(filename, 'rb')
    return util.FileStream(input, size)

The size argument is optional and is used to set the Content-Length HTTP header; you should provide it whenever possible.

Discussion

Note that not all Quixote server modules support streaming. Most notably, for Quixote <= 1.0b1 the quixote.server.twisted_http module simply converts the contents of the stream into an in-memory string. All Quixote 2 servers currently support streamed responses.

Also note that FileStream does not currently close the file after streaming is finished. Perhaps it should.


CategoryCookbook CategoryQuixote1


2010-09-22 22:14