Dynamic image rendering example with cherrypy

1,063 views
Skip to first unread message

spock

unread,
Dec 23, 2007, 3:53:09 PM12/23/07
to cherrypy-users
import cherrypy
from cherrypy import tools
from pylab import *
from numpy import *
import os
# To execute : python root.py then open your web browser at the
appropriate cherrypy web server port. e.g :
# http://localhost:8080

class Root:
@cherrypy.expose
def index(self):
return """<html>
<head></head>
<body>
Please enter alpha value:
<form action="visu" method="post">
<input type="text" name="alph" value="1.0" />
</form>
</body>
</html>
"""

@cherrypy.expose
def showimage(self):
cherrypy.response.headers['Content-Type']= "image/png"
f = open("sin.png", "rb")
contents = f.read()
f.close()
return contents


@cherrypy.expose
def visu(self, alph = 1.0):
_header = """
<html>
<head>
<title>Random notes</<title>
<link rel="stylesheet" type="text/css" href="/style.css"></link>
</head>
<body>
<div class="container">"""
_footer = """
</div>
</body>
</html>"""
ioff()
x = arange(0, 10, 0.01)
alpha = eval(alph)
subplot(1,2,1), plot(x, sin(alpha*x), '.-')
subplot(1,2,2), plot(x,sin(alpha*x*cos(alpha*x)), 'o-')
savefig("sin.png", dpi=96)
cherrypy.response.headers['Content-Type']= 'text/html'
page = [_header]
page.append('<img src="/showimage/" width="800" height="400" />' )
page.append(_footer)
return page

if __name__ == '__main__':
cherrypy.quickstart(Root())

Arnar Birgisson

unread,
Dec 27, 2007, 3:59:47 AM12/27/07
to cherryp...@googlegroups.com
Hi there,

Some comments inline:

Beware of the glaring security problem there, you are eval()ing input
controlled by the remote user.

> subplot(1,2,1), plot(x, sin(alpha*x), '.-')
> subplot(1,2,2), plot(x,sin(alpha*x*cos(alpha*x)), 'o-')
> savefig("sin.png", dpi=96)

You might want to think about concurrency here, unless there is only
one user. Reusing the same filename sin.png could lead to problems
where one user's request to visu happens between another one's
requests to visu and showimage, effectively overwriting sin.png before
the latter can retreive his.

One idea is to use the tempfile module to generate a unique temporary filename:
http://docs.python.org/lib/module-tempfile.html

Perhaps a better idea, is to output the image data directly to the
response, without saving it to disk. Judging by

http://matplotlib.sourceforge.net/matplotlib.pyplot.html#-savefig

savefig can accept a file-like object instead of a filename. In this
case, you would move the code that generates the plot to showimage,
and call savefig with a StringIO instance as the first parameter, and
return its value directly.

buf = StringIO()
savefig(buf, dpi=96, format='png')
return buf.getvalue()


> cherrypy.response.headers['Content-Type']= 'text/html'
> page = [_header]
> page.append('<img src="/showimage/" width="800" height="400" />' )
> page.append(_footer)
> return page
>
> if __name__ == '__main__':
> cherrypy.quickstart(Root())


cheers,
Arnar

Reply all
Reply to author
Forward
0 new messages