我正在尝试在Python 3中创建一个允许我在远程计算机上轻松执行函数的构造。 假设我已经有了一个python tcp服务器,它将运行它收到的函数,在远程服务器上运行,我现在正在寻找使用像
这样的装饰器@execute_on(address, port)
这将创建执行正在装饰的函数所需的必要上下文,然后将函数和上下文发送到远程计算机上的tcp服务器,然后执行它。首先,这有点理智吗?如果没有,你能推荐一个更好的方法吗?我做了一些谷歌搜索,但没有找到满足这些需求的东西。
我为tcp服务器和客户端实现了一个快速而又脏的实现,所以相当确定它会工作。我可以通过
获得一个字符串表示函数(例如func)传递给装饰器import inspect
string = inspect.getsource(func)
然后可以将其发送到可以执行它的服务器。问题是,如何获取该函数执行所需的所有上下文信息?例如,如果func定义如下,
import MyModule
def func():
result = MyModule.my_func()
MyModule需要在全局上下文或远程服务器上的funcs本地上下文中用于func。在这种情况下,这是相对微不足道的,但根据何时以及如何使用import语句,它会变得更加复杂。在Python中有一种简单而优雅的方法吗?我现在提出的最好的方法是使用ast库来提取所有import语句,使用inspect模块获取这些模块的字符串表示,然后在远程服务器上重建整个上下文。不是特别优雅,我可以看到很多错误的空间。
感谢您的时间
答案 0 :(得分:2)
除非远程服务器受到某种程度的强烈保护或“极度沙盒化”(例如BSD“jail”),否则您概述的方法风险极大 - 任何可以向其发送功能的人都可以在那里运行任意代码。
假设您拥有一个完全信任的身份验证系统,那么您实现了“脆弱性”问题 - 该函数可以依赖于执行时其模块中定义的任何全局变量(可能与您可以使用的不同)通过检查来检测:在执行时确定导入模块的集合,更一般地说是全局变量,是图灵完备的问题。)
你可以通过序列化函数的全局变量以及函数本身来处理全局问题,当你发送它以进行远程执行时(无论你是以可读的字符串形式序列化所有这些东西,还是以其他方式,是小问题)。但是这仍然会让您在函数中执行导入问题。
除非你愿意在“远程”功能上加上一些限制,例如“函数内部没有导入(以及从它调用的函数)”,我认为你可以拥有服务器覆盖__import__
(所有import语句使用的内置函数,旨在被覆盖以满足特殊需求,例如你的;-)从发送客户端请求额外的模块(当然,这要求所述客户端也具有“类似服务器”的能力,因为它必须能够响应来自服务器的这种“模块请求”。
你不能对远程函数施加一些限制,将这项任务带回到理智的范围内......?
答案 1 :(得分:2)
您可能对 execnet 项目感兴趣。
execnet提供经过仔细测试的方法,可以跨版本,平台和网络障碍轻松与Python解释器进行交互。它有一个最小和快速的API,目标是以下用途:
http://codespeak.net/execnet/example/test_info.html#get-information-from-remote-ssh-account
我见过它的演示。但我自己从未使用它。
答案 2 :(得分:1)
从您的问题中不清楚是否存在某些系统限制/要求以这种方式解决您的问题。如果没有,可以使用某种消息传递基础设施更轻松,更快捷地实现此目的。
例如,您可以考虑[Celery] [1]
[1]:http://ask.github.com/celery/getting-started/introduction.html将满足您的需求。
答案 3 :(得分:0)
你的最终目标是什么?从你的描述中我可以看出你没有理由不能创建一个简单的消息类并发送它的实例来命令远程机器做'东西'..?
无论你做什么,你的远程机器都需要执行Python源代码,为什么不在那里分发代码然后再运行呢?你可以创建一个简单的服务器来接受一些python源文件,解压它们导入相关的模块,然后运行一个命令?
答案 4 :(得分:0)
这可能很难做到,你会遇到安全问题,争论等问题。 也许你可以远程运行一个Python解释器,可以使用套接字或HTTP服务给代码,而不是按函数级别在函数上执行?