In my case i have a database with document thumbnails that are displayed on an overview page. Every time the browser visits the site all thumbnail images are downloaded again and so the download function loads again all the images from the database. Since i am running on GAE this drives up my database-reads enormous.
I tried to enable client site caching by setting:
@auth.requires_login()
def download():
response.headers['Cache-Control'] = None
response.headers['Pragma'] = None
response.headers['Expires'] = None
return response.download(request, db)
I also read that response.stream may help but the web2py book says:
As noted above, response.download should be used to retrieve files stored via an upload field. response.stream can be used in other cases, such as returning a temporary file or StringIO object created by the controller.
— EDIT —
I got the client side caching enabled with:
session.forget() #important
expire_time = datetime.timedelta(days=2)
response.headers['Cache-Control'] = 'private, max-age%d'%(60*60*24*2)
response.headers['Pragma'] = None
response.headers['Expires'] = (request.utcnow + expire_time).strftime("%a, %d %b %Y %H:%M:%S GMT")
response.headers['Content-Disposition'] = \
'attachment;filename=' + filename + ';'
return response.stream(stream, filename=filename)
First, if the images are publicly available and do not require authentication to view, then instead of storing them in the /uploads folder, you can store them in the /static folder and then simply serve them as static files. In that case, the headers will be set automatically for client side caching (it will also be faster and more efficient).
Second, you can use
response.stream()to stream uploaded files, but it won’t automatically identify the folder where the file is located nor decode the original filename from the encoded filename and add it to the Content-Disposition header (which you don’t need in this case anyway because you are displaying the images and not downloading them). So, as long as you pass the full file path toresponse.stream(), you should be able to use it in this case, and it will set the response headers appropriately for caching.Finally, if you want to set the response headers directly, it would be something like: