[python] Node.js에서 Python 함수를 호출하는 방법

Express Node.js 응용 프로그램이 있지만 Python에서 사용할 기계 학습 알고리즘도 있습니다. 기계 학습 라이브러리의 강력한 기능을 활용하기 위해 Node.js 애플리케이션에서 Python 함수를 호출 할 수있는 방법이 있습니까?



답변

내가 아는 가장 쉬운 방법은 노드와 함께 제공되는 “child_process”패키지를 사용하는 것입니다.

그런 다음 다음과 같은 작업을 수행 할 수 있습니다.

const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',["path/to/script.py", arg1, arg2, ...]);

그런 다음 모든 당신이해야 할 메이크업은 있는지입니다 import sys파이썬 스크립트 한 다음에 액세스 할 수는 arg1사용하여 sys.argv[1], arg2사용 sys.argv[2] , 등등.

노드로 데이터를 다시 보내려면 파이썬 스크립트에서 다음을 수행하십시오.

print(dataToSendBack)
sys.stdout.flush()

그런 다음 노드는 다음을 사용하여 데이터를 청취 할 수 있습니다.

pythonProcess.stdout.on('data', (data) => {
    // Do something with the data returned from python script
});

이렇게하면 스폰을 사용하여 여러 인수를 스크립트에 전달할 수 있으므로 인수 중 하나가 호출 할 함수를 결정하고 다른 인수는 해당 함수 등에 전달되도록 Python 스크립트를 재구성 할 수 있습니다.

이것이 분명하기를 바랍니다. 설명이 필요한지 알려주세요.


답변

Python을 사용하고 Node.js 애플리케이션에 머신 러닝 모델을 통합하려는 사람들을위한 :

child_process핵심 모듈을 사용합니다 .

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

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

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

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

        console.log(data.toString());
        res.write(data);
        res.end('end');
    });
})

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

필요하지 않습니다 sys파이썬 스크립트 모듈이 .

다음은 다음을 사용하여 작업을 수행하는 모듈 방식입니다 Promise.

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

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

    const { spawn } = require('child_process');
    const pyprog = spawn('python', ['./../pypy.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(fromRunpy) {
        console.log(fromRunpy.toString());
        res.end(fromRunpy);
    });
})

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


답변

python-shell의해 모듈extrabacon 은 Node.js에서 기본이지만 효율적인 프로세스 간 통신과 더 나은 오류 처리를 통해 Python 스크립트를 실행하는 간단한 방법입니다.

설치 : npm install python-shell .

간단한 파이썬 스크립트 실행하기 :

var PythonShell = require('python-shell');

PythonShell.run('my_script.py', function (err) {
  if (err) throw err;
  console.log('finished');
});

인수 및 옵션으로 Python 스크립트 실행

var PythonShell = require('python-shell');

var options = {
  mode: 'text',
  pythonPath: 'path/to/python',
  pythonOptions: ['-u'],
  scriptPath: 'path/to/my/scripts',
  args: ['value1', 'value2', 'value3']
};

PythonShell.run('my_script.py', options, function (err, results) {
  if (err)
    throw err;
  // Results is an array consisting of messages collected during execution
  console.log('results: %j', results);
});

전체 문서 및 소스 코드는 https://github.com/extrabacon/python-shell을 확인 하십시오.


답변

이제 zerorpc 와 같은 Python 및 Javascript를 지원하는 RPC 라이브러리를 사용할 수 있습니다

그들의 첫 페이지에서 :

Node.js 클라이언트

var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");

client.invoke("hello", "RPC", function(error, res, more) {
    console.log(res);
});

파이썬 서버

import zerorpc

class HelloRPC(object):
    def hello(self, name):
        return "Hello, %s" % name

s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()


답변

대부분의 이전 답변은 on ( “data”)에서 약속의 성공을 요구합니다. 많은 데이터를 수신하면 첫 번째 부분 만 얻을 수 있기 때문에이를 수행하는 올바른 방법은 아닙니다. 대신 최종 이벤트에서해야합니다.

const { spawn } = require('child_process');
const pythonDir = (__dirname + "/../pythonCode/"); // Path of python script folder
const python = pythonDir + "pythonEnv/bin/python"; // Path of the Python interpreter

/** remove warning that you don't care about */
function cleanWarning(error) {
    return error.replace(/Detector is not able to detect the language reliably.\n/g,"");
}

function callPython(scriptName, args) {
    return new Promise(function(success, reject) {
        const script = pythonDir + scriptName;
        const pyArgs = [script, JSON.stringify(args) ]
        const pyprog = spawn(python, pyArgs );
        let result = "";
        let resultError = "";
        pyprog.stdout.on('data', function(data) {
            result += data.toString();
        });

        pyprog.stderr.on('data', (data) => {
            resultError += cleanWarning(data.toString());
        });

        pyprog.stdout.on("end", function(){
            if(resultError == "") {
                success(JSON.parse(result));
            }else{
                console.error(`Python error, you can reproduce the error with: \n${python} ${script} ${pyArgs.join(" ")}`);
                const error = new Error(resultError);
                console.error(error);
                reject(resultError);
            }
        })
   });
}
module.exports.callPython = callPython;

요구:

const pythonCaller = require("../core/pythonCaller");
const result = await pythonCaller.callPython("preprocessorSentiment.py", {"thekeyYouwant": value});

파이썬 :

try:
    argu = json.loads(sys.argv[1])
except:
    raise Exception("error while loading argument")


답변

노드 10과 자식 프로세스에 1.0.2있습니다. 파이썬의 데이터는 바이트 배열이며 변환해야합니다. 파이썬에서 http 요청을하는 또 다른 간단한 예입니다.

마디

const process = spawn("python", ["services/request.py", "https://www.google.com"])

return new Promise((resolve, reject) =>{
    process.stdout.on("data", data =>{
        resolve(data.toString()); // <------------ by default converts to utf-8
    })
    process.stderr.on("data", reject)
})

request.py

import urllib.request
import sys

def karl_morrison_is_a_pedant():
    response = urllib.request.urlopen(sys.argv[1])
    html = response.read()
    print(html)
    sys.stdout.flush()

karl_morrison_is_a_pedant()

노드의 http 모듈이 내가해야 할 몇 가지 요청을로드하지 않기 때문에 ps는 고안된 예가 아닙니다.


답변

파이썬을 가져 와서 번역 한 다음 자바 스크립트처럼 호출 할 수 있습니다. 나는 이것을 screeps를 위해 성공적으로 해왔고 심지어 브라우저에서 la brython 으로 실행되도록했다 .