I use the output of a Python script in my node.js app.
However, I need to query it another time (and, possibly, several times).
I cannot do this because the Python process ends and cannot be restarted. I tried to reassign the variable, but it doesn't work. How to launch the Python script again? Here is my code:
var spawn = require('child_process').spawn,
interval_data = [1,2,4,5,6,7],
interval_dataString = '';
var py = undefined
startPython()
py.stdout.on('data', function(data){
interval_dataString += data.toString();
console.log(interval_dataString)
});
py.stdout.on('end', function(){
console.log('Alpha Component =',interval_dataString);
setTimeout(() => {
startPython()
},1000)
});
function startPython() {
py = undefined
py = spawn('python', ['dfa.py'])
py.stdin.write(JSON.stringify(interval_data));
py.stdin.end();
}
Here's the Python code:
## compute_input.py
import sys, json, numpy as np
#Read data from stdin
def read_in():
lines = sys.stdin.readlines()
#Since our input would only be having one line, parse our JSON data from that
return json.loads(lines[0])
#lines = "[1,2]" # for testing
#return json.loads(lines) # for testing
def main():
#get our data as an array from read_in()
lines = read_in()
#create a numpy array
np_lines = np.array(lines)
#use numpys sum method to find sum of all elements in the array
lines_sum = np.sum(np_lines)
#return the sum to the output stream
print(lines_sum)
#start process
if __name__ == '__main__':
main()
You override the child process. So you can no longer use the original object (event emitter).
Its simpler then you tought maybe:)
Just call/move the event emitter stuff inside the "start" function. So every time you spawn the child, you use the new child object/event emitter.
const { spawn } = require("child_process");
const interval_data = [1, 2, 4, 5, 6, 7]
const interval_response = [];
// use this as exit strategie
var should_restart = true;
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
interval_response.push(data.toString());
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response.join());
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// Do what ever you want with the result here
}
});
// write stuff to python child process
child.stdin.write(JSON.stringify(interval_data));
}
start();
// let the programm run for min. 5sec
setTimeout(() => {
should_restart = false;
}, 5000);
Tested with your python code.
node index.js
Alpha Component = 3
Alpha Component = 3
,3
Alpha Component = 3
,3
,3
Alpha Component = 3
,3
,3
,3
DIE! [ '3\n', '3\n', '3\n', '3\n', '3\n' ]
I thought you actually read in your python script from stdin. (And not only a dummy function)
But for the node part it should not make any difdrence.
Tested on Ubuntu 18.04 x64, node: v13.14.0, python: 3.6.9.
EDIT :
Created based on your python snippet, a script that reads from stdin and create a sum out of all numbers passed:
import sys, json
def main():
data = sys.stdin.read()
data = json.loads(data)
#print("debug:", data)
chunks_sum = sum(data)
#print("debug", chunks_sum)
sys.stdout.write(str(chunks_sum))
#start process
if __name__ == '__main__':
main()
Modified start function:
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
// since your python code just create
// a sum of all numbers, store the
// returend stuff as number
interval_response.push(Number(data));
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response);
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// create sum of all sum chunks from python
// not sure what you want to do with the "interval_response" array
// just for demo purpose
let sum = interval_response.reduce((pv, cv) => pv + cv, 0);
console.log("Total sum", sum);
}
});
// write stuff to python child process
//child.stdin.write();
child.stdin.end(JSON.stringify(interval_data));
}
Changed child.stdin.write
to child.stdin.end
, so does python now it can "start" and dosnt has to wait for more data.
Note: i dont know how IPC/stdio "buffering" work. Perhaps you expirence some fishy things if you work with large data.
More, we store the data from python that is writen to "stdout" as number in the array interval_response
, since you just calculate the total sum of the data we write to "stdin".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.