невозможно запустить файл python из Node.js

#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);
})();