Слияние двух кодов - PullRequest
       8

Слияние двух кодов

1 голос
/ 26 февраля 2020

У меня есть 2 файла в Node js. Я хочу объединить эти 2, но я столкнулся с проблемой .. Этот файл вызывает функцию из python file

const app = express()

let runPy = new Promise(function(success, nosuccess) {

    const { spawn } = require('child_process');
    const pyprog = spawn('python', ['./ml.py']);

    pyprog.stdout.on('data', function(data) {

        success(data);
    });

    pyprog.stderr.on('data', (data) => {

        nosuccess(data);
    });
});

app.get('/', (req, res) => {

    res.write('welcome\n');

    runPy.then(function(testMLFunction) {
        console.log(testMLFunction.toString());
        res.end(testMLFunction);
    });
})
app.listen(4000, () => console.log('Application listening on port 4000!'))

python file ml. py

def testMLFunction():
return "hello from Python"

print (testMLFunction ())

Ниже файл работает при нажатии кнопки с методом записи

var fs = require('fs');

var server = http.createServer(function (req, res) {

    if (req.method === "GET") {
        res.writeHead(200, { "Content-Type": "text/html" });
        fs.createReadStream("./form.html", "UTF-8").pipe(res);
    } else if (req.method === "POST") {

        var result = "";
        req.on("data", function (chunk) {
            console.log(chunk.toString());

            result = chunk;
            //body=body.toUpperCase;
        });

        req.on("end", function(){
            res.writeHead(200, { "Content-Type": "text/html" });
            res.end(result);
        });
    }

}).listen(3000);

как я могу это сделать ..

1 Ответ

0 голосов
/ 26 февраля 2020

Здесь несколько вещей не так. Я объясню как можно проще.

  1. Вы забыли добавить в свой код var express = require('express')
  2. Обещание, которое вы дали, runPy, должно быть заключено в функцию, тогда как ваш подход немедленно запустит обещание при загрузке самого скрипта.
  3. Вы resolving/rejecting при первом входящем выводе, вы не должны этого делать, потому что вы не сможете узнать, что на самом деле произошло в оболочке , Вам необходимо сохранить эти выходные строки, это единственный способ узнать, что говорит сценарий.
  4. В runPy вы должны разрешить / отклонить событие pyprogr close .
  5. Вы не можете напрямую получить доступ к методу другого скрипта, независимо от того, что это за тип файла py, sh, bat, js. Тем не менее, вы можете получить доступ к его внутренним функциям, передав аргументы в оболочку, и, конечно, этот скрипт должен иметь логи c, необходимые для работы с этими аргументами.
  6. При использовании spawn / exec Вы должны иметь в виду, что ВЫ НЕ являетесь пользователем, выполняющим сценарий, а node, поэтому возможны разные результаты.
  7. Самое главное, ваш целевой сценарий должен PRINT/ECHO для оболочки, никаких возвратов ! Наилучшим подходом было бы напечатать некоторую строку json и проанализировать ее в javascript после закрытия оболочки, чтобы вы могли иметь доступ к объекту вместо строки.

Ниже найду демо для вашего случая использования, я изменил файл python, чтобы он мог что-то напечатать.

ml.py

print('I\'m the output from ml.py')

index. js

const express = require('express');
const app = express()

let runPy = function () { // the promise is now wrapped in a function so it won't trigger on script load
    return new Promise(function (success, nosuccess) {

        const {spawn} = require('child_process');
        const pyprog = spawn('python', ['./ml.py'], {shell: true}); // add shell:true so node will spawn it with your system shell.

        let storeLines = []; // store the printed rows from the script
        let storeErrors = []; // store errors occurred
        pyprog.stdout.on('data', function (data) {
            storeLines.push(data);
        });

        pyprog.stderr.on('data', (data) => {
            storeErrors.push(data);
        });
        pyprog.on('close', () => {
            // if we have errors will reject the promise and we'll catch it later
            if (storeErrors.length) {
                nosuccess(new Error(Buffer.concat(storeErrors).toString()));
            } else {
                success(storeLines);
            }
        })
    })
};

let path = require('path');
app.use(express.json());
app.use(express.urlencoded({ extended: true })); // you need to set this so you can catch POST requests
app.all('/', (req, res) => { // i've change this from .get to .all so you can catch both get and post requests here

    console.log('post params', req.body);

    if(req.body.hasOwnProperty('btn-send')){

        runPy()
            .then(function (pyOutputBuffer) {

                let message = 'You sent this params:\n' +JSON.stringify(req.body, null,2) + '\n';
                message += Buffer.concat(pyOutputBuffer).toString();

                res.end(message);

            })
            .catch(console.log)
    }else{
        res.sendFile(path.join(__dirname,'form.html')); // you need an absolute path to 'file.html'
    }

});
app.listen(4000, () => console.log('Application listening on port 4000!'));

form. html

<div>hello there</div>
<form action="/" method="post">
    <input type="text" value="" name="some-text"/>
    <button type="submit" value="1" name="btn-send" >Press me!</button>
</form>
...