使用 Python 动态执行主程序外的 py 文件时(支持自定义 scprit)时遇到的 reload 问题(importlib)

2020-12-07 21:22:53 +08:00
 among
一个 flask 的应用,需要支持用户自定义的 script 脚本,脚本也是 py 的。
自定义的 py 脚本经常会改,但是 flask 不能经常重启,当前使用的方式为:


trigger = importlib.import_module(TS_NAME)
importlib.reload(trigger)
sc_res = trigger.check(*TS_ARGS, **self.kwargs)


外部的 script 中,默认有个 check 的 方法,只需要执行这个方法。

现在遇到的问题包括:
1:需要 sys.path.append(LIB_PATH),LIB_PATH 为自定义脚本所在目录,要不然找不到;
2:使用 import_module 来 import,是根据文件名来 import, 为了防止修改,每次都 reload ;
3:lib 的顺序问题,因为是根据 name 来 import,如果 2 个自定义脚本的路径不一样,但是 name 一样,就会导致顺序问具体,永远执行的是在 lib 中最靠前的那个,会引起不可预料的问题;
4:一旦有个用户在里面写 exit(),那 flask 的主程序也就挂了。


目前虽然可以规避,但并不是一个安全可控的解决方案,设计这个主要的目的是为了实现,可以让用户自定义 script,进行整个系统的定制和二次开发。

不知道有没有其他好的解决方案,可以在保证灵活性的基础上,又能够实现安全可控。
1585 次点击
所在节点    Python
6 条回复
ClericPy
2020-12-07 22:00:25 +08:00
公司文化全程拒绝服务走离线工具, 所以最近也折腾类似的, 软件工具都带着依赖被我打包成 pyz 单文件丢在 nas 挂盘直接导入了, 结果遇到 reload 当场翻车

然后工作全用 typed 或者 fire 做成命令行版本调用了(stdout / stdin)... 总算能跑通了, 至于优化什么的, 还是不去过度设计了, 又不是做艺术品, 能跑就得了
no1xsyzy
2020-12-07 22:15:18 +08:00
用多进程呢?开个工作进程跑用户脚本得到 trigger module 对象,然后把参数传过去调用执行,结果传回。
fasionchan
2020-12-08 08:52:05 +08:00
关于第一、二、三点,可以尝试自行将自定义脚本内容读入、编译、然后执行,得到你想要的 check 方法,不需要依赖 import 机制。具体做法可以参考我写的文章: https://www.imooc.com/read/76/article/1918

关于第四点,二次开发本来就要对系统的安全性负责,做好用户隔离即可。用户隔离要最好做到系统级别的隔离,进程级别的隔离是不够的:如果一个用户执行了关机指令,另一个用户躺着中枪?
hahaba
2020-12-08 09:26:14 +08:00
最好用线程去处理,子线程死掉,不会影响父线程
krixaar
2020-12-08 09:57:45 +08:00
搞成跨进程通信(再来个 flask 然后 request 疯狂 post ),或者集成个 Lupa 然后让用户写 lua 脚本,你这边做个控制台给每个脚本安优先级数字,跑的时候按优先级来。
kaneg
2020-12-08 12:23:40 +08:00
这个程序是跑在你们的服务器还是用户自己的?
如果是你们的,如果运行环境不做隔离或者限制,用户的代码可以做很多危险的事,比如获取系统敏感信息,删除文件等。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/733100

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX