programing

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

yoursource 2022. 10. 22. 13:32
반응형

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로 python에 할 수 .arg1를 사용합니다.sys.argv[1],arg2를 사용합니다.sys.argv[2]기타 등등.

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

print(dataToSendBack)
sys.stdout.flush()

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

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

이를 통해 여러 인수를 spen을 사용하여 스크립트에 전달할 수 있으므로 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-shellextrabaconNode.js: Python은 Python을 사용합니다.기본적이지만 효율적인 프로세스 간 통신과 보다 나은 오류 처리를 제공합니다.

설치:

포함: npm 께께 :npm install python-shell.

실: 는는실실 or or or:yarn add python-shell

간단한 Python 스크립트 실행:

const PythonShell = require('python-shell').PythonShell;

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

인수 및 옵션을 사용하여 Python 스크립트 실행:

const PythonShell = require('python-shell').PythonShell;

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 를 참조해 주세요.

Python이나 Javascript(zerorpc 등)를 지원하는 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"("데이터")에서 약속의 성공이라고 합니다. 많은 데이터를 수신하면 첫 번째 부분만 표시되므로 적절한 방법이 아닙니다.대신 마지막 이벤트에서 해야 돼요.

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

python:

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

그 예들 중 상당수는 몇 년 전의 것으로 복잡한 설정이 관련되어 있습니다.JSPyBridge/pythonia를 사용해 보십시오(완전 공개:제가 작가입니다.)외부 Python 객체가 JS에 존재하는 것처럼 조작할 수 있는 Vanilla JS입니다.실제로 Python 코드가 콜백 및 전달 함수를 통해 JS를 호출할 수 있도록 상호 운용성을 실현합니다.

numpy + matplotlib 예제, ES6 가져오기 시스템 사용:

import { py, python } from 'pythonia'
const np = await python('numpy')
const plot = await python('matplotlib.pyplot')

// Fixing random state for reproducibility
await np.random.seed(19680801)
const [mu, sigma] = [100, 15]
// Inline expression evaluation for operator overloading
const x = await py`${mu} + ${sigma} * ${np.random.randn(10000)}`

// the histogram of the data
const [n, bins, patches] = await plot.hist$(x, 50, { density: true, facecolor: 'g', alpha: 0.75 })
console.log('Distribution', await n) // Always await for all Python access
await plot.show()
python.exit()

CommonJs 경유(최상위 대기 없음):

const { py, python } = require('pythonia')
async function main() {
  const np = await python('numpy')
  const plot = await python('matplotlib.pyplot')
  ...
  // the rest of the code
}
main().then(() => python.exit()) // If you don't call this, the process won't quit by itself.

노드 10과 자생 프로세스 중1.0.2python의 데이터는 바이트 배열이므로 변환해야 합니다.python에서 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)
})

부탁한다.화이

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()

p.s. 노드의 http 모듈이 필요한 몇 가지 요청을 로드하지 않기 때문에 의도된 예가 아닙니다.

당신은 당신의 비단뱀을 가져다가 전치하고 자바스크립트처럼 부를 수 있다.나는 이것을 스크리프용으로 성공적으로 실행했고 심지어 브라우저에서도 실행시켰다.

Boa는 당신의 요구에 적합하다. Python tensorflow를 확장한 예를 보라.keras.Sequential클래스(JavaScript.

const fs = require('fs');
const boa = require('@pipcook/boa');
const { tuple, enumerate } = boa.builtins();

const tf = boa.import('tensorflow');
const tfds = boa.import('tensorflow_datasets');

const { keras } = tf;
const { layers } = keras;

const [
  [ train_data, test_data ],
  info
] = tfds.load('imdb_reviews/subwords8k', boa.kwargs({
  split: tuple([ tfds.Split.TRAIN, tfds.Split.TEST ]),
  with_info: true,
  as_supervised: true
}));

const encoder = info.features['text'].encoder;
const padded_shapes = tuple([
  [ null ], tuple([])
]);
const train_batches = train_data.shuffle(1000)
  .padded_batch(10, boa.kwargs({ padded_shapes }));
const test_batches = test_data.shuffle(1000)
  .padded_batch(10, boa.kwargs({ padded_shapes }));

const embedding_dim = 16;
const model = keras.Sequential([
  layers.Embedding(encoder.vocab_size, embedding_dim),
  layers.GlobalAveragePooling1D(),
  layers.Dense(16, boa.kwargs({ activation: 'relu' })),
  layers.Dense(1, boa.kwargs({ activation: 'sigmoid' }))
]);

model.summary();
model.compile(boa.kwargs({
  optimizer: 'adam',
  loss: 'binary_crossentropy',
  metrics: [ 'accuracy' ]
}));

완전한 예는 https://github.com/alibaba/pipcook/blob/master/example/boa/tf2/word-embedding.js에 있습니다.

저는 자바스크립트 개발자들의 머신러닝 문제를 해결하기 위해 Boa를 다른 프로젝트 Pipcook에서 사용하였습니다. 우리는 Boa 라이브러리에 의해 Python 생태계(tensorflow, keras, pytorch)에 ML/DL 모델을 구현하였습니다.

/*eslint-env es6*/
/*global require*/
/*global console*/
var express = require('express'); 
var app = express();

// Creates a server which runs on port 3000 and  
// can be accessed through localhost:3000
app.listen(3000, function() { 
    console.log('server running on port 3000'); 
} ) 

app.get('/name', function(req, res) {

    console.log('Running');

    // Use child_process.spawn method from  
    // child_process module and assign it 
    // to variable spawn 
    var spawn = require("child_process").spawn;   
    // Parameters passed in spawn - 
    // 1. type_of_script 
    // 2. list containing Path of the script 
    //    and arguments for the script  

    // E.g : http://localhost:3000/name?firstname=Levente
    var process = spawn('python',['apiTest.py', 
                        req.query.firstname]);

    // Takes stdout data from script which executed 
    // with arguments and send this data to res object
    var output = '';
    process.stdout.on('data', function(data) {

        console.log("Sending Info")
        res.end(data.toString('utf8'));
    });

    console.log(output);
}); 

이건 나한테 효과가 있었어.이 코드 스니펫의 경로 변수에 python.exe를 추가해야 합니다.또한 python 스크립트가 프로젝트 폴더에 있는지 확인하십시오.

const util = require('util');
const exec = util.promisify(require('child_process').exec);
    
function runPythonFile() {
  const { stdout, stderr } = await exec('py ./path_to_python_file -s asdf -d pqrs');
  if (stdout) { // do something }
  if (stderr) { // do something }
}

자세한 내용은 공식 Nodejs 자녀 프로세스 페이지(https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback를 참조하십시오.

언급URL : https://stackoverflow.com/questions/23450534/how-to-call-a-python-function-from-node-js

반응형