问题描述
我有一个其中包含ML模型的Python文件,当我与cmd分开运行时,它可以正常工作。
我目前正在尝试在特定路线上发布时从节点运行它。
但是,直到现在,我仍无法运行python脚本。
到目前为止,我已经在节点中使用了两个模块, 我用过child_process,我也用过@ fridgerator / pynode。
1- @ fridgerator / pynode引起的问题是它不断发出错误, ModuleNotFoundError:没有名为“ team_match_prediction3”的模块 无法加载模块:team_match_prediction3
team_match_prediction3是我与node.js文件一起放置的python文件名:
以下是带有@ fridgerator / pynode模块的Node.js路由的代码:
endpoints.MapFallbackToFile("index.html").RequireAuthorization();
我从以下网站找到了这个pynode代码段: https://thecodinginterface.com/blog/bridging-nodejs-and-python-with-pynode/
2-然后我使用了子进程模块,该模块引起的问题是 stdout.on(“ data”)方法没有运行,甚至无法运行等待python脚本完成,然后运行 python.on('close')函数。
这是child_process部分的node.js代码:
router.post(("/team"),(req,res) =>
{
let regressionModel = {};
pynode.startInterpreter();
pynode.appendSysPath('./');
pynode.openFile('team_match_prediction3');
let team_1 = req.body.Team1;
let team_2 = req.body.Team2;
new Promise((resolve,reject) => {
try {
if (_.isEmpty(regressionModel)) {
console.log('calling python');
regressionModel = pynode.call('starting_func',team_1,team_2);
}
resolve(regressionModel);
} catch(err) {
console.log(err);
reject('Failed to load Teams variables');
}
})
.then(response => res.send(response))
.catch(err => res.err(err));
});
当我使用子进程模块时,它只是提供一个console.log,该进程以pid 2结尾,这几乎立即发生,并且不发送任何数据作为响应。
关于python文件,对于pynode模块,我刚刚创建了一个要由pynode调用的函数,该函数仅调用clean_and_predict函数,该函数刚刚返回了所需的数据,
但是当我使用子进程时, 我只是在python文件中的全局级别执行此操作:
//The import
const {spawn} = require('child_process');
router.post(("/team"),res) =>
{
let team_1 = req.body.Team1;
let team_2 = req.body.Team2;
const python = spawn('python',['./team_match_prediction3.py',team_2]);
let dataToSend = [];
python.stdout.on('data',(data) => {
console.log('Pipe data from python script ...');
dataToSend.push(data);
});
// in close event we are sure that stream from child process is closed
python.on('close',(code) => {
console.log(`child process close all stdio with code ${code}`);
// send data to browser
res.send(`THis is result : ${dataToSend}`);
});
和clean_and_predict函数完成其工作,最后,仅打印出所需的数据,然后执行:
team_1 = sys.argv[1]
team_2 = sys.argv[2]
semi = [(team_1,team_2)]
clean_and_predict(semi,ranking,final,rf)
final_answer是Winner的字典,名称是赢得板球队的名字。
对于如何解决此问题或是否应该使用新模块的任何想法,将不胜感激。
解决方法
我能够解决此问题,首先我通过提供存储server.js文件的文件夹的路径而不是路由器文件调用python文件的路径,部分解决了文件未找到错误。
另一个问题是等待python文件执行并从中获取结果,我使用npm模块execa来做到这一点,
这是节点中调用并等待python文件的部分:
const execa = require('execa');
然后在发布路线中
let team_1 = req.body.Team1;
let team_2 = req.body.Team2;
const subprocess = execa('python
path/to/pythonfile/from/serve.js/folder',[team_1,team_2]);
subprocess.stdout.pipe(process.stdout);
(async () => {
const {stdout} = await subprocess;
// Returning Result:
res.send(stdout);
console.log('child output:',stdout);
})();