我有一个Express Node.js应用程序,但我也有一个机器学习算法在Python中使用。是否有一种方法可以从我的Node.js应用程序调用Python函数来利用机器学习库的强大功能?


当前回答

之前的大多数答案都将承诺的成功称为on(“数据”),这不是正确的方法,因为如果你收到很多数据,你只会得到第一部分。相反,你必须在end事件上做。

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

其他回答

之前的大多数答案都将承诺的成功称为on(“数据”),这不是正确的方法,因为如果你收到很多数据,你只会得到第一部分。相反,你必须在end事件上做。

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

您现在可以使用支持Python和Javascript的RPC库,例如zerorpc

从他们的头版:

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

Python服务器

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

你可以在NPM上查看我的套餐 https://www.npmjs.com/package/@guydev/native-python

它提供了一种非常简单而强大的方式来从node运行python函数

import { runFunction } from '@guydev/native-python'

const example = async () => {
   const input = [1,[1,2,3],{'foo':'bar'}]
   const { error, data } = await runFunction('/path/to/file.py','hello_world', '/path/to/python', input)

   // error will be null if no error occured.
   if (error) {
       console.log('Error: ', error)
   }

   else {
       console.log('Success: ', data)
       // prints data or null if function has no return value
   }
}

python模块

# module: file.py

def hello_world(a,b,c):
    print( type(a), a) 
    # <class 'int'>, 1

    print(type(b),b)
    # <class 'list'>, [1,2,3]

    print(type(c),c)
    # <class 'dict'>, {'foo':'bar'}

你可以把你的python编译,然后像调用javascript一样调用它。我已经成功地为screeps做了这件事,甚至让它在浏览器中运行la brython。

Boa很适合您的需求,请参阅扩展Python tensorflow keras的示例。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

我在另一个项目pipook中使用了Boa,这是为了解决JavaScript开发人员的机器学习问题,我们通过Boa库在Python生态系统(tensorflow,keras,pytorch)上实现了ML/DL模型。