PythonShell messages received only at the end of the python script execution in Electron

Viewed 390

I'm trying to create an Electron app that executes a Python script but I cannot retrieve messages from python before the end of the script.

This is the code at the beginning of the file main.js:

const { PythonShell } = require('python-shell');

let pyshell = new PythonShell('app.py');

console.log("MAIN: Script started")

pyshell.on('message', function (message) {
  console.log("Message from APP: " + message);
});

// end the input stream and allow the process to exit
pyshell.end(function (err, code, signal) {
  if (err) throw err;
  console.log('The exit code was: ' + code);
  console.log('The exit signal was: ' + signal);
  console.log('finished');
});

let seconds = 0
setInterval(function(){ 
  seconds = seconds + 5
  console.log("MAIN: " + seconds + " seconds"); }, 5000);

This is the python script:

import sys
import time

print("START")
time.sleep(10)
print("After 10 seconds")

This is the shell:

MAIN: Script started
MAIN: 5 seconds
MAIN: 10 seconds
Message from APP: START
Message from APP: After 10 seconds
The exit code was: 0
The exit signal was: null
finished
MAIN: 15 seconds
2 Answers

Ok I found this answer on the github forum.

"Output is likely being buffered, meaning you did not send enough data to flush the buffer at least once. Closing stdin (by ending the process) forces the buffer to flush, causing your app to receive data. This is very common, you typically don't want to write every single byte as it would be too IO intensive."

https://github.com/extrabacon/python-shell/issues/8

So I changed my code app.py code to

import sys
import time

print("START")
sys.stdout.flush()
time.sleep(10)
print("After 10 seconds")

and now the output is correct

MAIN: Script started
Message from APP: START
MAIN: 5 seconds
MAIN: 10 seconds
Message from APP: After 10 seconds
The exit code was: 0
The exit signal was: null
finished
MAIN: 15 seconds

I don't know if there are other better solutions, but with this one it works

Please use flush in the print function of Python

print('Python started from NODE.JS', flush=True)
Related