Hello,
Do you need the graphics files to remain around for a while, or are
they dynamically generated for one request? If the former, the
approach being discussed here makes a lot of sense. The files you
create will be around until you delete them yourself. If the latter
(read data from constantly-updated source, make graph, put on page --
that sort of thing), you may be better suited rendering the graphics
into a temporary file (as created with tempfile.NamedTemporaryFile or
whatever) and streaming it to the client yourself.
# at the top of the controller file
import tempfile
class ChunkedFileIter(object):
"""An iterator interface which reads chunks of a given size from a file
until the file ends.
"""
def __init__(self, fileobj, blocksize = 8192):
"""Initialize this object.
:Parameters:
fileobj : object supporting ``read(blocksize)``
File object from which to read
blocksize : integer
Number of bytes to read in each iteration
"""
self.fileobj = fileobj
self.blocksize = blocksize
def __iter__(self):
return self
def next(self):
"""Read ``self.blocksize`` bytes from ``self.fileobj``. Raises
``StopIteration`` when the file ends."""
dat = self.fileobj.read(self.blocksize)
if not dat:
raise StopIteration
return dat
# in your action:
tf = tempfile.NamedTemporaryFile(suffix='.png')
# Write graphic into the file named by
tf.name
makeGraphic(
tf.name)
# tf.flush() # <-- may be necessary if you write the file yourself,
as opposed to an external program
tf.seek(0)
response.content_type='image/png'
response.app_iter = ChunkedFileIter(tf)
Using the NamedTemporaryFile ensures that the file is deleted after
the request ends. You can then instruct the browser to cache its copy
of the file (using etag_cache()) so you don't regenerate it unless the
source data has changed or the client requests a new copy explicitly.
That totally won't help if you need those PNGs laying around for
future use...but as it took about five minutes of cut-and-paste...if
it does help...great!
Cheers,
Matt Z.