python-shell icon indicating copy to clipboard operation
python-shell copied to clipboard

Synchronized execution of python script

Open dhaval-lila opened this issue 6 years ago • 12 comments

Is there way trun python script in sync with node

function() {
   let pyshell = new PythonShell('.myscript.py')
let content = ""
    pyshell.on('message',function(message){
        content = message
    })
return content // content needs to be message instead due to async nature it returns empty string
}

dhaval-lila avatar Jan 24 '19 08:01 dhaval-lila

Look at the readme - you want the run command.

Almenon avatar Jan 24 '19 15:01 Almenon

I am guessing you meant PythonShell.run() that one too is async function. It takes callback function.

dhaval-lila avatar Jan 25 '19 05:01 dhaval-lila

Oh yeah you're right, sorry. We don't have a synchronous option but that's a good idea

Almenon avatar Jan 25 '19 05:01 Almenon

If you are looking to add this feature , I will gladly help and I was looking to contribute and this is great opportunity for my first contribution I am familiar with node and related web technologies so can you guide me through what i need to know to implement synchronous option

dhaval-lila avatar Jan 25 '19 10:01 dhaval-lila

Thanks! For sychronus operation first we need to migrate to using promises (read #77). I've created a v2 branch for this: https://github.com/extrabacon/python-shell/tree/version2

Once we are using promises then we can make sync versions of our functions - see this article: https://medium.com/@patarkf/synchronize-your-asynchronous-code-using-javascripts-async-await-5f3fa5b1366d

Almenon avatar Jan 25 '19 16:01 Almenon

I want to ask don't it already come true

WingDust avatar Jan 10 '20 16:01 WingDust

+1

abrichr avatar Feb 04 '20 00:02 abrichr

re-posting my comment from #77:

To be honest I'm probably not going to get to this anytime soon. I'd be happy to review a PR if someone submits it. Or if someone wants to donate to charity I can use that as motivation to get around to implementing this.

Almenon avatar Feb 04 '20 04:02 Almenon

We had the same issue today, and ended up promisifying it like so:

function someFunction(date, data){
  return new Promise((resolve, reject) => {
    let result;
    let pyshell = new PythonShell('pyshell_test.py', {mode: 'text', args: [date]});
    
    pyshell.send(JSON.stringify(data['someProperty']));
    
    pyshell.on('message', function (message) {
      result = JSON.parse(message);
    });
    
    pyshell.on('stderr', function (stderr) {
      console.log(stderr);
    });
    
    pyshell.end(function (err, code, signal) {
      if (err) reject(err);
      console.log('The exit code was: ' + code);
      console.log('The exit signal was: ' + signal);
      console.log('finished');
      resolve(result);
    });
    
  });
}

nkhil avatar Feb 21 '20 10:02 nkhil

@nkhil this works (at least for now), thanks. :)

balanikaran avatar May 01 '21 12:05 balanikaran

@nkhil implementation worked for me but I did something more like this in a Class:

callPythonScript = () => {
	return new Promise((resolve, reject) => {
		PythonShell.run(this.pythonScriptName, this.options, (err, result) => {
			if (err) reject(err);

			resolve(result);
		});
	});
};

AlexString avatar Apr 02 '22 19:04 AlexString

@nkhil implementation worked for me but I did something more like this in a Class:

callPythonScript = () => {
	return new Promise((resolve, reject) => {
		PythonShell.run(this.pythonScriptName, this.options, (err, result) => {
			if (err) reject(err);

			resolve(result);
		});
	});
};

One should use return reject(err) to avoid resolving the request afterwards. See https://stackoverflow.com/questions/32536049/do-i-need-to-return-after-early-resolve-reject

dschweinbenz avatar Jan 10 '23 08:01 dschweinbenz