nishant kumar
nishant kumar

Reputation: 517

executing python script through nodejs

I am trying to execute this piece of node js code which execute a python script. Through this code works fine. but the response "running" and "finished" are displayed on front end immediately. "finshed" has to be displayed once the execution of python scripts gets completed.

app.post('/execute', function(request, response){
    response.write("running");
    console.log("executing")
    var pyshell = new PythonShell('./python_codes/test.py')
    pyshell.on('message', function (message) {console.log(message);});
    pyshell.end(function (err) {if (err){throw err;};console.log('finished');});
    response.write("finished");
    response.end();
});

Upvotes: 1

Views: 1350

Answers (2)

Ezzat
Ezzat

Reputation: 901

You should add your response inside the callback function

app.post('/execute', function(request, response){

  response.setHeader('Connection', 'Transfer-Encoding'); 
  response.setHeader('Content-Type', 'text/html; charset=utf-8');

  response.write("running");
  console.log("executing")
  var pyshell = new PythonShell('./python_codes/test.py')
  pyshell.on('message', function (message) {console.log(message);});
  pyshell.end(function (err) {
    if (err){
      throw err;
    };
    console.log('finished');
    response.write("finished");
    response.end();
  });
});

Upvotes: 1

Fredrick Brennan
Fredrick Brennan

Reputation: 7357

It happens because the PythonShell class is asynchronous. What your code is doing is creating a PythonShell object, storing it in variable pyshell, and then adding a few events to the pyshell object. It then directly continues to write "finished".

Because writing "finished" is not part of the callback for the end() function, it happens right away. I see at least three things you can do:

  1. If the HTTP library you are using supports it, just add the response.write("finished"); response.end(); code to the pyshell.end callback.
  2. Call Python using a library which supports pausing the current execution thread (or use execSync). This is bad practice, because it defeats the purpose of using a concurrent framework like node.js, but would work.
  3. Use WebSockets (or socket.io, which works even if WebSockets aren't available, such as through CloudFlare) to transmit the "finished" message.

Upvotes: 1

Related Questions