views:

51

answers:

2

I have an app written in python. I want to give my users the ability to manipulate the apps objects by allowing them to run their own scripts. They are likely to make errors in their scripts. If there is an error I want to ensure that the app doesn't stop running. I'd like to embed a debugger in my app to help them debug their scripts.

e.g. I define a point class in my app in shapes.py:

class QVPoint(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def addPoint(self, aPoint):
        self.x = self.x + aPoint.x
        self.y = self.y + aPoint.y

I want to enable them to run scripts like:

from shapes import QVPoint
a = QVPoint(1,1)
a.addPoint(QVPoint(2,2))
print "<" + str(a.x) + ',' + str(a.y) + ">"
print "<%d,%d>" % (a.x, a.y)
print 'done'

I figure this must use the interpreter, the debugger but I'm not sure on two counts, 1) how to expose objects that are created in the App to the script, and 2) how to ensure that the app doesn't stop if a bug causes the script to stop.

I'm sure this must have been asked before but I can't find it. All answers welcome.

Many thx

David

+3  A: 

I would suggest you use a separate interpreter instance (separate python process) to evaluate user's scripts. This will guarantee that whatever breaks in the user script would never affect you application. You can run external processes using os module, this would be one way to do so: http://docs.python.org/library/os.html#os.popen

You can allow user's scripts to import certain module(s) from your application so that the variables you define are accessible by the scripts.

Alexander Finn
Just a note that `subprocess` is recommended over `os` for starting external processes.
David Zaslavsky
True, sorry for this, subprocess is a better choice.
Alexander Finn
+1  A: 

There are a few decisions to be made.

  1. Do you want to run it in the same process of your app or in a separate process?

    Without knowing much detail of your app, I'd tend to favor running them in a separate process. Use the subprocess module for this. You can create an app launcher that in turn calls your users script. If it throws an exception you can catch it and format the result and report back to the user.

  2. Do you want to expose the classes to your user or the objects to your user?

    In your example, it seems sharing the classes is enough. This should be fairly simple.

    If it is only classes, you can simply include it in the PYTHONPATH. Then your user can just import them. If you want to expose an object, it may requires you to do this in process. Or otherwise you have to find a way to serialize you objects and transfer it to the new process.

Wai Yip Tung
Just to clarify, I'm looking to share objects as well as classes. If I use a subprocess then I'll need to create proxies and stubs to communicate between the two processes - which seems more work than should be needed. It also means that anyone who wants to extend the app needs to write proxies and stubs which is definitely not desirable.
DangerMouse