Pylons tip #5 – Streaming static files

Pylons makes it super easy to return data to a client. You just return a string from your controller method!

class HelloController(BaseController):
 
    def index(self):
        return 'Hello World!'

Very nice. However, what if you want to serve up a potentially quite large file to the client? Sure, you could read the file into memory, and then return the entire buffer, but that is not very efficient. If you have a multi-megabyte file, you end up wasting lots of memory.

What you want to do, actually, is read a chunk of the file at a time, and then send that. So instead of reading the entire file into memory and returning it in a single go, you do lots of little chunks.

Simple conceptually. How do you do this in Pylons? Thankfully you can do this with a Python generator. Instead of returning a buffer, you return a generator:

class ImageController(BaseController):
 
    def index(self, id):
        ''' Stream local image contents to client '''
        try:
            imgf = open("%s/%s" %(config['image_data_dir'],
                os.path.basename(id)), 'r')
        except IOError:
            abort(404)
        def stream_img():
            chunk = imgf.read(1024)
            while chunk:
                yield chunk
                chunk = imgf.read(1024)
            imgf.close()
        return stream_img()

This works quite nicely. Hope that helps!

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">