Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js Python-shell: while true loop not working

Tags:

python

node.js

I've this simple Python script print out a message every second:

#!/usr/bin/python
import time

while True:
    print u"Message"
    time.sleep(1)

I'm trying to integrate a 3rd party Python script with the above structure with Node.js using python-shell.

I'm having this JS script to get all messages from the Python script:

var PythonShell = require('python-shell');

var options = {
  scriptPath: './'
};

var pyshell = new PythonShell('test.py',options);

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement) 
  console.log(message);
});

// end the input stream and allow the process to exit 
pyshell.end(function (err) {
  if (err) throw err;
  console.log('finished');
});

But it seems, that the while True in Python cause that the on-event is not called. How can I solve this? Can I change the loop inside the Python script to something compatible with python-shell?

like image 425
dhrm Avatar asked May 08 '26 20:05

dhrm


1 Answers

You need to flush sys.stdout as the output is buffered because it is piped:

import time
import sys
while True:
    print u"Message"
    sys.stdout.flush()
    time.sleep(1)

You will receive the output immediately once flushed:

$ nodejs n.js
Message
Message
Message
.....

You may be able to set the buffering to line buffered or unbuffered when you start the shell but I am not overly familiar with nodejs.

There is actually a way to set the -u flag to get unbuffered output with the pythonOptions flag:

var PythonShell = require('python-shell');

var pyshell = new PythonShell('test.py',{scriptPath:"./", pythonOptions: ['-u']});

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement) 
  console.log(message);

});

// end the input stream and allow the process to exit 
pyshell.end(function (err) {
  if (err) throw err;
  console.log('finished');
});

The output will be unbuffered so there will be no need to flush stdout.

like image 55
Padraic Cunningham Avatar answered May 10 '26 14:05

Padraic Cunningham



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!