stdout stdin node to python

Question:

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’?

Asked By: bbartling

||

Answers:

This code leaves a python process running, and sends messages and receives messages back from a python script.

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.

Answered By: Alex028502
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.