1
votes

I'm writing a simple web app to get a handle on how node child processes work. Basically you enter your name into an angular frontend which passes the name to an express backend in a javascript object. The backend passes the name as an argument to a simple python script as a command line argument using the child_process module. Theres nothing wrong with the front end and the name gets successfully passed to the backend but when I call stdout on the python process it doesn't work. There aren't any error messages.

Heres the express code:

app.post('/api', (req, res, next) => {
  console.log(req.body.name);

  const spawn = require('child_process').spawn;

  const process = spawn('python3', ['./hello.py', req.body.name]);

  process.stdout.on('data', (data) => {
    console.log(data);
    res.status(200).json({greeting: data});
  });
});

I put two console.log statements in the code to debug it. The first one prints the data but the second one inside the stdout function isn't called at all. The python script is in the same folder as the app.js express file so I'm pretty sure theres nothing wrong with the file path.

Here's the python script:

import sys

print('hello' + sys.argv[1])
sys.stdout.flush()

When I run it in the command line it works exactly as expected but I included it anyway just in case.

2
There's a great repository which already implements interfacing between node.js and python. In a very similar to your way. Maybe it will serve as a solution and source of inspiration for your purposes: github.com/extrabacon/python-shellUfos

2 Answers

0
votes

Process.stdout.on will keep on streaming until the end event. The code is wrong because you are actually sending response for every time there is some value in stdout. And you cant set the response header more than once. Try writing the code in below way. Thanks

 let output;
Process.stdout.on("data", (data) => {
      output += data;
});

Process.on("end", () => {
     // send response here
});
0
votes

close will trigger when your data completes

app.get("/list-account", async (req, res) => {
try {
let array = "";
let response = await child.spawn(
path.join(__dirname, "xcv-alpha-keychain.exe"),
["listaccounts"]
);
await response.stdout.on("data", (data) => {
const stdout = data.toString();
console.log("stdout", stdout);
array += stdout;
// return res.status(200).json({ array });
});
response.stderr.on("data", (data) => {
return res.status(500).send(data.toString());
});
response.on("error", (error) => {
return res.status(500).send({ error });
});
response.on("close", (code) => {
return res.status(200).json({ array, code });
});

} catch (error) {
return res.status(500).send(["a", "b", "c"]);
}
});