1

As of right now I am using the built in child_process to start up the Python script and listen for any data passed back via stdout.on('data', (data)) like in line 6 of the first JS code. But from the Google searches I have done I only see examples of one thing being passed back or a group of things being passed back all clumped together. I was wondering if it was possible to send back more than just one argument. Below is my code:

JS:

const spawn = require('child_process').spawn;
pythonProcess = spawn('python', ["/path/to/python/file"]);

pythonProcess.stdout.on('data', (data) => {
    console.log(data);
});

Python:

import sys

var thing1 = "Cold";
var thing2 = "Hot";
var thing3 = "Warm";

print(thing1);
print(thing2);
print(thing3);
sys.stdout.flush();

But what I want to happen is maybe pass back something like an array which is filled with the things I want to send back so that I can access them in the JS file like so:

const spawn = require('child_process').spawn;
pythonProcess = spawn('python', ["/path/to/python/file"]);

pythonProcess.stdout.on('data', (data) => {
    thing1 = data[0];
    thing2 = data[1];
    thing3 = data[2];
})

console.log('thing1: ' + thing1);
console.log('thing2: ' + thing2);
console.log('thing3: ' + thing3);

Which would output:

thing1: Hot
thing2: Cold
thing3: Warm

How would I do this?

Thanks in advance!

4
  • What you wrote there is not Python. Commented Jul 15, 2018 at 22:05
  • If you're just sending things over stdout, then you have to decide what data format you want to use. If it's just strings that would not themselves have commas in them, then they could just be comma separated strings and then the receiving end needs to parse them as they arrive. If it's just one chunk of data, then you may want to send JSON which is a predefined format that you can use library functions to both create and parse at both ends. Commented Jul 15, 2018 at 22:27
  • In addition, on the receiving end in node.js, you have no idea how much data will appear in any given data event. It could all come in one data event or it could be broken up into many separate data events. So, you either have to accumulate all the data until it says there is no more (child process is done) or examine what comes in incrementally and parse it incrementally when you recognize a whole piece that you can parse and keep the rest until the next data event comes in so you can combine it with that. Commented Jul 15, 2018 at 22:29
  • If your format is JSON, there are JSON stream readers that will do that for you on the node.js side of things so you just get events from them when a completed piece of JSON has been parsed (this is probably the simplest way to go if you have anything more than a few strings). Commented Jul 15, 2018 at 22:29

1 Answer 1

3

There isn't an interface that communicate directly between Node.js and Python, so you can't pass custom arguments, what you're doing is just executing a python program using child_process, so you don't send arguments, anything that is received on 'data' its what is printed to stdout from python.

So what you need to do, is serialize the data, and then deserialize it in Node, you can use JSON for this.

From your python script, output the following JSON object:

{
   "thing1": "Hot",
   "thing2": "Cold",
   "thing3": "Warm"
}

And in your Node.js script:

const spawn = require('child_process').spawn;
const pythonProcess = spawn('python', ["/path/to/python/file"]);

const chunks = [];

pythonProcess.stdout.on('data', chunk => chunks.push(chunk));

pythonProcess.stdout.on('end', () => {

    try {
        // If JSON handle the data
        const data = JSON.parse(Buffer.concat(chunks).toString());

        console.log(data);
        // {
        //    "thing1": "Hot",
        //    "thing2": "Cold",
        //    "thing3": "Warm"
        // }

    } catch (e) {
        // Handle the error
        console.log(result);
    }
});

Have in mind that data is chunked, so will have to wait until the end event is emitted before parsing the JSON, otherwise a SyntaxError will be triggered. (Sending JSON from Python to Node via child_process gets truncated if too long, how to fix?)

You can use any type of serialization you feel comfortable with, JSON is the easiest since we're in javascript.


Note that stdout is a stream, so it's asyncrhonous, that's why your example would never work.

pythonProcess.stdout.on('data', (data) => {
    thing1 = data[0];
    thing2 = data[1];
    thing3 = data[2];
})

// Things do not exist here yet
console.log('thing1: ' + thing1);
console.log('thing2: ' + thing2);
console.log('thing3: ' + thing3);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.