First of all, the python code you've posted is broken, if you did copy&paste
from your own script, then your code is invalid python because the indentation
is wrong.
Secondly, it's a bad idea to just execute a script with exec, this can be dangerous,
specially if you are not the owner of the script and how knows what the script
does.
So let's modify your root/externalFunc.py first: let's add a run method that
does the work of the script. Instead of just printing to the standard output,
the run function should return something, for example the a string or a
dictionary containing the results.
Because you haven't shown us the code of root/externalFunc.py, I assume that
the script may look like this:
#!/usr/bin/env python
# root/externalFunc.py
# old version
def run():
# ... doing some work,
# result is a variable with the result
print "Result: %d" % result
if __name__ == '__main__':
main()
Now let's modify it.
create an empty file __init__.py in the root/ directory:
// on linux/mac/bsd
$ touch root/__init__.py
// on windows
cmd> type NUL > root/__init__.py
This allows to use from root.whatever export something in another module.
- Let's add a
run method that actually does the work:
The new version:
#!/usr/bin/env python
# root/externalFunc.py
# new version
import sys
def run(parm1, param2, param3):
# ... doing some work,
# result is a variable with the result
return = {
"success": True,
"value": result
}
def main():
if len(sys.argv) != 4:
print >> sys.stderr, "usage: %s param1 param2 param3" % sys.argv
return 1
param1 = int(sys.argv[1])
param2 = sys.argv[2]
param3 = int(sys.argv[3])
res = run(param1, param2, param3)
if res["success"]:
print "Result: %d" % res["value"]
return 0
else:
print "Error, ..."
return 1
if __name__ == '__main__':
return main()
Now we have to change your server code to import the run method and use that
method instead of using exec or execfile
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from root.externalFunc import run as externalFunc_run
class KodeFunHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
param1 = 3
param2 = "max"
param3 = -12
res = externalFunc_run(param1, param2, param3)
if res["success"]:
answer = "The result is: %d" % res["value"]
else:
answer = "Error while computing externalFunc"
#send code 200 response
self.send_response(200)
#send header first
self.send_header('Content-type','text/plain')
self.end_headers()
# send answer
self.wfile.write(answer)
Now if you don't want (or cannot) change the code of root/externalFunc.py, or the script
is not a python script, then you could use subprocess.check_output.
import subprocess
import shlex
# bad, don't do that
# exec("root/externalFunc.py")
# do this instead
answer = subprocess.check_output(shlex.split("root/externalFunc.py params..."))
print "Answer: %s" % answer
Using subprocess.check_output is much more safe, behind the scenes it calls
subprocess.Popen, which executes a child program in a new process,
thus the child program won't cause damage if it goes bersek.
Now you can replace this line res = externalFunc_run(param1, param2, param3)
with the subprocess.check_output line.
root\externalFunc.pythere is now way to know. Thedo_GEThandler must send an answer to the request. I don't thinkroot\externalFunc.pydoes that for you. Why do you useexecfileanyway?http://127.0.0.1:80?