我希望能够通过在this tutorial
创建的Python服务器上发出请求来调用python脚本我希望当服务器收到特定请求时,它会启动Python脚本。
我尝试了这个简单的代码但没有成功。我认为在GET
请求它会启动externalFunc.py
脚本。但事实并非如此。
#!/usr/bin/env python
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import os
#Create custom HTTPRequestHandler class
class KodeFunHTTPRequestHandler(BaseHTTPRequestHandler):
#handle GET command
def do_GET(self):
execfile("root\externalFunc.py")
def run():
print('http server is starting...')
#ip and port of servr
#by default http server port is 80
server_address = ('127.0.0.1', 80)
httpd = HTTPServer(server_address, KodeFunHTTPRequestHandler)
print('http server is running...')
httpd.serve_forever()
if __name__ == '__main__':
run()
我没有任何错误,只是没有任何反应。 我做错了什么?
编辑:这是客户提出的GET请求:
import sys
#get http server ip
http_server = '127.0.0.1'
#create a connection
conn = httplib.HTTPConnection(http_server)
#request command to server
conn.request('GET', '','')
#get response from server
rsp = conn.getresponse()
#print server response and data
print(rsp.status, rsp.reason)
data_received = rsp.read()
print(data_received)
conn.close()
我从服务器收到501错误:
127.0.0.1 - - [20/Jan/2018 15:46:46] code 501, message Unsupported method ('GET')
127.0.0.1 - - [20/Jan/2018 15:46:46] "GET / HTTP/1.1" 501 -
答案 0 :(得分:1)
首先,如果您进行了复制和粘贴,那么您发布的python代码就会被破坏 从你自己的脚本,然后你的代码是无效的python因为缩进 是错的。
其次,用exec
执行脚本是个坏主意,这可能很危险,
特别是如果你不是脚本的所有者,怎么知道脚本是什么
确实
首先让我们修改您的root/externalFunc.py
:让我们添加一个run
方法,
做脚本的工作。而不是仅仅打印到标准输出,
run
函数应该返回一些东西,例如一个字符串或一个
包含结果的字典。
因为您还没有向我们展示root/externalFunc.py
的代码,我认为是这样
脚本可能如下所示:
#!/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()
现在让我们修改它。
在__init__.py
目录中创建一个空文件root/
:
// on linux/mac/bsd
$ touch root/__init__.py
// on windows
cmd> type NUL > root/__init__.py
这允许在另一个模块中使用from root.whatever export something
。
run
方法:新版本:
#!/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()
现在我们必须更改您的服务器代码以导入run
方法并使用它
方法而不是使用exec
或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)
现在,如果您不想(或不能)更改root/externalFunc.py
或脚本的代码
不是python脚本,那么你可以使用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
使用subprocess.check_output
在它调用的幕后更加安全
subprocess.Popen
,在新流程中执行子计划,
因此,如果儿童计划成为bersek,则不会造成损害。
现在您可以替换此行res = externalFunc_run(param1, param2, param3)
使用subprocess.check_output
行。