#python #node.js #express #child-process
#python #node.js #экспресс #дочерний процесс
Вопрос:
у меня есть файл Python, в котором есть модель ML, и он отлично работает, когда я запускаю его отдельно от cmd.
в настоящее время я пытаюсь запустить его с узла всякий раз, когда я отправляю сообщение по определенному маршруту.
Но до сих пор мне не удалось запустить скрипт python.
До сих пор я использовал два модуля в node, я использовал child_process и я также использовал @fridgerator / pynode.
1- Проблема, возникающая с @fridgerator / pynode, заключается в том, что он постоянно выдает ошибку ModuleNotFoundError: Ни одному модулю с именем ‘team_match_prediction3’ не удалось загрузить модуль: team_match_prediction3
team_match_prediction3 — это имя файла python, которое я поместил вместе с node.js файл :
Ниже приведен код Node.js маршрут с помощью модуля @fridgerator / pynode :
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») не был запущен, и он даже не стал ждать завершения скрипта python, а просто запустил функцию python.on(‘close’).
Это node.js код для части child_process:
//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}`);
});
когда я использую модуль дочернего процесса, он просто выдает консоль.зарегистрируйте, что процесс завершился с 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 имеет название команды-победителя по крикету.
Любая идея о том, как это исправить или следует ли использовать новый модуль, будет оценена по достоинству, спасибо.
Ответ №1:
я смог решить эту проблему, во-первых, я частично решил ошибку file not found, указав путь из папки, в которой 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);
})();