无法从 Node.js 运行 python 文件
unable to run python file from Node.js
我有一个 Python 文件,里面有一个 ML 模型,当我 运行 它与 cmd 分开时,它工作得很好。
我目前正在尝试 运行 每当我 post 在特定路线上时从节点 运行 它。
但是,直到现在,我还没有 运行 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路由的代码:
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));
});
我从这个网站找到了这个 pynode 代码片段:https://thecodinginterface.com/blog/bridging-nodejs-and-python-with-pynode/
2- 然后我使用了子进程模块,该模块出现的问题是 stdout.on("data") 方法不是运行ning,它甚至不会等待 python 脚本完成,只是 运行 python.on('close')函数。
这是 child_process 部分的 node.js 代码:
//The import
const {spawn} = require('child_process');
router.post(("/team"),(req, res) =>
{
let team_1 = req.body.Team1;
let team_2 = req.body.Team2;
const python = spawn('python', ['./team_match_prediction3.py' , team_1,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}`);
});
当我使用子进程模块时,它只给出一个 console.log 以 pid 2 结束的进程,这几乎立即发生,并且不发送任何数据作为响应。
关于 python 文件,对于 pynode 模块,我刚刚创建了一个由 pynode 调用的函数,它只调用 clean_and_predict 函数,该函数刚刚返回所需的数据,
但是当我使用子进程时,
我只是在 python 文件中在全局级别执行此操作:
team_1 = sys.argv[1]
team_2 = sys.argv[2]
semi = [(team_1,team_2)]
clean_and_predict(semi, ranking, final, rf)
和 clean_and_predict 函数完成它的工作,最后,只打印出所需的数据,我做 :
print(final_answer["Winner"])
sys.stdout.flush()
final_answer 是一个 dict,其中 Winner 具有获胜板球队的名称。
任何关于如何解决这个问题或是否应该使用新模块的想法都将不胜感激,谢谢。
我能够解决这个问题,首先我通过提供存储 server.js 文件的文件夹的路径而不是调用 python 的路由器文件来部分解决找不到文件的错误文件。
另一个问题是等待 python 文件执行并从中获取结果,我使用 npm 模块 execa 来执行此操作,
这是调用和等待python文件的节点部分:
const execa = require('execa');
然后在 post 路线中:
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);
})();
我有一个 Python 文件,里面有一个 ML 模型,当我 运行 它与 cmd 分开时,它工作得很好。
我目前正在尝试 运行 每当我 post 在特定路线上时从节点 运行 它。
但是,直到现在,我还没有 运行 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路由的代码:
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));
});
我从这个网站找到了这个 pynode 代码片段:https://thecodinginterface.com/blog/bridging-nodejs-and-python-with-pynode/
2- 然后我使用了子进程模块,该模块出现的问题是 stdout.on("data") 方法不是运行ning,它甚至不会等待 python 脚本完成,只是 运行 python.on('close')函数。
这是 child_process 部分的 node.js 代码:
//The import
const {spawn} = require('child_process');
router.post(("/team"),(req, res) =>
{
let team_1 = req.body.Team1;
let team_2 = req.body.Team2;
const python = spawn('python', ['./team_match_prediction3.py' , team_1,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}`);
});
当我使用子进程模块时,它只给出一个 console.log 以 pid 2 结束的进程,这几乎立即发生,并且不发送任何数据作为响应。
关于 python 文件,对于 pynode 模块,我刚刚创建了一个由 pynode 调用的函数,它只调用 clean_and_predict 函数,该函数刚刚返回所需的数据,
但是当我使用子进程时, 我只是在 python 文件中在全局级别执行此操作:
team_1 = sys.argv[1]
team_2 = sys.argv[2]
semi = [(team_1,team_2)]
clean_and_predict(semi, ranking, final, rf)
和 clean_and_predict 函数完成它的工作,最后,只打印出所需的数据,我做 :
print(final_answer["Winner"])
sys.stdout.flush()
final_answer 是一个 dict,其中 Winner 具有获胜板球队的名称。
任何关于如何解决这个问题或是否应该使用新模块的想法都将不胜感激,谢谢。
我能够解决这个问题,首先我通过提供存储 server.js 文件的文件夹的路径而不是调用 python 的路由器文件来部分解决找不到文件的错误文件。
另一个问题是等待 python 文件执行并从中获取结果,我使用 npm 模块 execa 来执行此操作,
这是调用和等待python文件的节点部分:
const execa = require('execa');
然后在 post 路线中:
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);
})();