I am trying to learn how to pass data back and forth between node and Python using stdin and stdout.
This is something super bare bones where the node app.js
calls the Python file test.py
.
app.js
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python3',["test.py"]);
pythonProcess.stdout.on('data', (data) => {
mystr = data.toString();
myjson = JSON.parse(mystr);
console.log(myjson.Data);
});
test.py
import sys,json
data = {"devices":{
"boiler":{
"address":"12345:2",
"object_type":"analogInput",
"object_instance":"2"
},
"cooling_plant":{
"address":"12345:2",
"object_type":"analogInput",
"object_instance":"2"
},
"air_handler_1":{
"address":"12345:2",
"object_type":"analogInput",
"object_instance":"2"
},
"air_handler_2":{
"address":"12345:2",
"object_type":"analogInput",
"object_instance":"2"
},
"hot_water_valve_1":{
"address":"12345:2",
"object_type":"analogInput",
"object_instance":"2"
}
}}
resp = {
"Response": "Success",
"Message": "from Python string",
"Data": data
}
print(json.dumps(resp))
sys.stdout.flush()
When I run $ node app
I can see the json data from the python script in the console.
Next to zero wisdom here, question I have is it possible to keep a "running" python script with a function where through stdin and stdout I can pass data from node to the running Python script function?
This seems to be exactly what the npm package python-shell
can do from there page.
Would anyone be able to give me some advise on how I could pass a string like this:
"12345:2 analogInput 2"
And have the Python script return the same string via a function as json with using `python-shell'?
CodePudding user response:
Here is an answer to a slightly simpler question - we'll see if that is helpful. It leaves a python process running, and sends messages and receives messages back from a python script. Feel free to down-vote this if I am way off:
app.js:
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python3',["-u", "test.py"]);
pythonProcess.stdout.on('data', (data) => {
console.log("PYTHON SENT:", data.toString());
});
let count = 0;
setInterval(function() {
pythonProcess.stdin.write(`12345:2 analogInput ${count }\n`);
}, 1000);
test.py
import sys
print("READY")
for line in sys.stdin:
print("PYTHON RECEIVED: %s" % line.strip())
here is what happens
$ node app.js
PYTHON SENT: READY
PYTHON SENT: PYTHON RECEIVED: 12345:2 analogInput 0
PYTHON SENT: PYTHON RECEIVED: 12345:2 analogInput 1
PYTHON SENT: PYTHON RECEIVED: 12345:2 analogInput 2
PYTHON SENT: PYTHON RECEIVED: 12345:2 analogInput 3
I used python stdin to send messages to the python process every second, and then have that callback you wrote process the output each time.
To do stuff like this, you usually need the python argument -u
or it will buffer the output, so you won't see anything until you exit.