У меня есть файл Python, в котором есть модель ML, и он отлично работает, когда я запускаю его отдельно от cmd.

В настоящее время я пытаюсь запускать его с узла всякий раз, когда я публикую по определенному маршруту.

Но до сих пор мне не удавалось запустить скрипт python.

До сих пор я использовал два модуля в узле, я использовал child_process, а также использовал @ холодильник / pynode.

1- Проблема, возникающая с @ Refrigerator / pynode, заключается в том, что он постоянно выдает ошибку, ModuleNotFoundError: нет модуля с именем team_match_prediction3 Не удалось загрузить модуль: team_match_prediction3

Team_match_prediction3 - это имя файла python, которое я поместил вместе с файлом node.js:

Ниже приведен код маршрута Node.js с модулем @ холодильник / 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}`);
            });

Когда я использую модуль дочернего процесса, он просто дает 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 обозначает победившую команду по крикету.

Приветствуются любые идеи о том, как это исправить или следует ли использовать новый модуль, спасибо.

0
FaisalShakeel 22 Сен 2020 в 22:42

1 ответ

Лучший ответ

Мне удалось решить эту проблему, во-первых, я частично решил ошибку «файл не найден», указав путь из папки, в которой хранился файл server.js, вместо файла маршрутизатора, вызывающего файл python.

Другая проблема заключалась в ожидании выполнения файла python и получении от него результата, для этого я использовал модуль npm module 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);
})();



0
FaisalShakeel 26 Сен 2020 в 12:31