node-calls-python - call Python from NodeJS directly in-process without spawning processes
Suitable for running your ML or deep learning models from Node directly
Installation
npm install node-calls-python
Installation FAQ
Sometimes you have to install prerequisites to make it work.
Linux: install node, npm, node-gyp, python3, python3-dev, g++ and make
Install Node
sudo apt install curl
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt install nodejs
Install Python
sudo apt install python3
sudo apt install python3-dev
Install Node-gyp
sudo apt install make
sudo apt install g++
sudo npm install -g node-gyp
NodeJS and Python
Windows: installInstall Node-gyp if missing
npm install --global --production windows-build-tools
npm install -g node-gyp
Examples
Calling a simple python function
Let's say you have the following python code in test.py
import numpy as np
def multiple(a, b):
return np.multiply(a, b).tolist()
Then to call this function directly you can do this in Node
const nodecallspython = require("node-calls-python");
let py = nodecallspython.interpreter;
py.import("test.py").then(async function(pymodule) {
let result = await py.call(pymodule, "multiple", [1, 2, 3, 4], [2, 3, 4, 5]);
console.log(result);
});
Or to call this function by using the synchronous version
const nodecallspython = require("node-calls-python");
let py = nodecallspython.interpreter;
py.import("test.py").then(async function(pymodule) {
let result = py.callSync(pymodule, "multiple", [1, 2, 3, 4], [2, 3, 4, 5]);
console.log(result);
});
Creating python objects
Let's say you have the following python code in test.py
import numpy as np
class Calculator:
vector = []
def __init__(self, vector):
self.vector = vector
def multiply(self, scalar, vector):
return np.add(np.multiply(scalar, self.vector), vector).tolist()
Then to instance the class directly in Node
const nodecallspython = require("node-calls-python");
let py = nodecallspython.interpreter;
py.import("test.py").then(async function(pymodule) {
let pyobj = await py.create(pymodule, "Calculator", [1.4, 5.5, 1.2, 4.4]);
let result = await py.call(pyobj, "multiply", 2, [10.4, 50.5, 10.2, 40.4]);
});
Or to instance the class synchronously and directly in Node
const nodecallspython = require("node-calls-python");
let py = nodecallspython.interpreter;
py.import("test.py").then(async function(pymodule) {
let pyobj = py.createSync(pymodule, "Calculator", [1.4, 5.5, 1.2, 4.4]);
let result = await py.callSync(pyobj, "multiply", 2, [10.4, 50.5, 10.2, 40.4]); // you can use ayns version (call) as well
});
Doing some ML with Python and Node
Let's say you have the following python code in logreg.py
from sklearn.datasets import load_iris, load_digits
from sklearn.linear_model import LogisticRegression
class LogReg:
logreg = None
def __init__(self, dataset):
if (dataset == "iris"):
X, y = load_iris(return_X_y=True)
else:
X, y = load_digits(return_X_y=True)
self.logreg = LogisticRegression(random_state=42, solver='lbfgs', multi_class='multinomial')
self.logreg.fit(X, y)
def predict(self, X):
return self.logreg.predict_proba(X).tolist()
Then you can do this in Node
const nodecallspython = require("node-calls-python");
let py = nodecallspython.interpreter;
py.import("logreg.py")).then(async function(pymodule) { // import the python module
let logreg = await py.create(pymodule, "LogReg", "iris"); // create the instance of the classifier
let predict = await py.call(logreg, "predict", [[1.4, 5.5, 1.2, 4.4]]); // call predict
console.log(predict);
});
See mode examples here
Supported data mapping
From Node to Python
- undefined to None
- null to None
- boolean to boolean
- number to double
- int32 to long
- uint32 to long
- int64 to long
- string to unicode (string)
- array to list
- object to dictionary
From Python to Node
- None to undefined
- boolean to boolean
- double to number
- long to int64
- unicode (string) to string
- list to array
- tuple to array
- set to array
- dictionary to object