Saturday, April 29, 2006

CherryPy is great!

Inspired by Ian Bicking's HTConsole, I wanted to see if I could get a simple "Python compiler", similar to Lightning Compiler but using a browser window instead of basing it on wxPython. Having no experience with any web programming, and looking at Ian's code, I thought it would take me forever to get this going. Also, I didn't really want to have to learn about all the packages used by Ian to produce HTConsole.

After a few simple attempts with Python's webbrowser module, a fruitless query on comp.lang.python, and some wandering on the web, I came accross CherryPy. To be honest, I had heard of CherryPy before, but had never looked at it as I thought it was something I would never need.

Lo and behold, simply after reading the basic tutorials included with CherryPy, I was able to write a very small program which does pretty much the same thing that earlier versions of Lightning Compiler could do. The complete code is included below:

import cherrypy
import os
from tempfile import gettempdir
TMP_DIR = gettempdir()

class PythonRunner(object):
title = 'Play with Python'

def header(self):
return '''
<html>
<head>
<title>%s</title>
</head>
<body>
<h2>%s</h2>
''' % (self.title, self.title)

def footer(self):
return '''
</body>
</html>
'''

def index(self, code=None):
cherrypy.session['code'] = code
output = ''
if code is None:
cherrypy.session['output'] = ''
else:
tmp_filename = os.path.join(TMP_DIR, 'my_file.dat')
f = open(tmp_filename, 'w')
f.write(code)
f.close()
f_in, f_out = os.popen4("python %s"%tmp_filename)
output = "The result of"
output += "<pre><font color='blue'>%s</font></pre>is: "%code
output += "<pre><font color='green'>"
for line in f_out.readlines():
output += line
output += "</font></pre>"
cherrypy.session['output'] = output
return self.header()+'''
Type in your Python code.
<form action="index" method="GET">
<textarea name="code" rows=5 cols=80></textarea><br/>
<input type="submit" value="Run Python"/>
</form>
<br/>
%s
''' % output + self.footer()
index.exposed = True

cherrypy.root = PythonRunner()
cherrypy.config.update({'session_filter.on': True})

if __name__ == '__main__':
cherrypy.config.update(file = 'tutorial.conf')
cherrypy.server.start()
And here's what it looks like (html code simply pasted below; it doesn't work here!)

Play with Python



Type in your Python code.





The result of
def hello():
print 'Hello from CherryPy!'
hello()
a = 3
print a*3
is:
Hello from CherryPy!
9


Thank you CherryPy developpers!

9 comments:

francois said...

Hello,

I also find CherryPy great :)

Just a question: I've seen that you have syntax color in your Python code (in this Blogger post).

Can I ask you how you did that ? (I didn't any find any "code" button in Blogger and tried a "code" tag without success).

Thanks

cheers

André said...

When creating a new post in blogger, there is an editor with a small toolbar. One of the option is to highlight some text and assign it a color from a palette. So, the coloring is done "by hand" in a WYSIWYG fashion.

francois said...

Ok I thought that there was maybe a kind of pulgin.
Thanks for the answer and for you interesting blog.

francois

Christian said...

Glad you are enjoying CherryPy! It is quite easy to get going, and once you start, you can't stop. You've been warned ;-)

Christian

Ashysh said...

Hi,
I am using Cherrypy to write a small application as well. I needed help on how do I pass or use variables defined in one function, in another function.
Also, how do you pass data to and from HTML code to the python(cherrypy) code.

Thnx,
Ashysh

André said...

ashysh:

As I mentioned, the complete code I used is given in the blog. It's all there!


Shortly after doing this simple example, I stopped using CherryPy. So I never got to use it beyond the simple example I gave you. I seem to recall that there is a CherryPy discussion group - you might be able to get some answers there.

sukadeb said...

I have cherrypy3.0.0 installed in my computer. When i pasteed this code in my machine and ran it after fixing the indentations it is giving the following error. Can you please suggest me what is the problem

The path '/' was not found.

Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/cherrypy/_cprequest.py", line 342, in respond
cherrypy.response.body = self.handler()
File "/usr/lib/python2.5/site-packages/cherrypy/_cperror.py", line 199, in __call__
raise self
NotFound: (404, "The path '/' was not found.")

André said...

To sukadeb:

I do not use CherryPy (other than that one experiment I did a while ago), and have no idea as to what could cause this traceback.

Try asking your question on the cherrypy user group
http://groups.google.com/group/cherrypy-users?hl=en

Amarisse said...

sukadeb:

Try with this:


root = YourClassName()
if __name__ == '__main__':
import os.path
conf = os.path.join(os.path.dirname(__file__), 'YourConfigFile.conf')
cherrypy.quickstart(root,config=conf)

In my version using 'mount root.blahblahblah' doesn't work, so i had to spend some hours to make it work.
It's good idea to read cherrypy's tutorial also. Look for it in:
/usr/lib/python2.5/site-packages/cherrypy/tutorial
I found my solution there.