2

I have the following Python script:

import sys 
print("Output from Python") 
print("First name: " + sys.argv[1]) 
print("Last name: " + sys.argv[2]) 

I am trying to call this script from a Node.js server and I have read online two ways of doing this:

The first is by using PythonShell:

const app = require('express')();
const ps = require('python-shell');

ps.PythonShell.run('hello.py', null, function (err, results) {
   if (err) throw err;
   console.log('finished');
   console.log(results);
});

app.listen(4000);

When trying to achive it this way I get the following error:

PythonShell.run is not a function.

I'm not sure if the path I wrote here is the correct one but I made sure the path I wrote in the server was correct.

The second way is by using child process:

var express = require('express'); 
var app = express(); 

  app.listen(3000, function() { 
  console.log('server running on port 3000'); 
} ) 

app.get('/name', callName); 
function callName(req, res) { 

var spawn = require("child_process").spawn; 
var process = spawn('python',["./hello.py", 
                    req.query.firstname, 
                    req.query.lastname] ); 


process.stdout.on('data', function(data) { 
    res.send(data.toString()); 
  } ) 
 } 

When trying this way I get the following error:

Error: spawn python ENOENT at Process.ChildProcess._handle.onexit (internal/child_process.js:246:19) at onErrorNT (internal/child_process.js:421:16) at process.internalTickCallback (internal/process/next_tick.js:72:19) Emitted 'error' event at: at Process.ChildProcess._handle.onexit (internal/child_process.js:252:12) at onErrorNT (internal/child_process.js:421:16) at process.internalTickCallback (internal/process/next_tick.js:72:19)

Does anyone know what the problem is? Or maybe suggest a different option?

mujuonly
  • 11,370
  • 5
  • 45
  • 75
keke
  • 53
  • 1
  • 8
  • Try to console.log your `ps` variable to see what contains. – Jorge Fuentes González Mar 11 '19 at 12:22
  • Also search for `ENOENT` on Google. Google is your friend :P – Jorge Fuentes González Mar 11 '19 at 12:22
  • @JorgeFuentesGonzález { PythonShellError: [Function: PythonShellError], PythonShell: { [Function: PythonShell] defaultPythonPath: 'py', defaultOptions: {}, format: { text: [Function: toText], json: [Function: toJson] }, parse: { text: [Function: asText], json: [Function: asJson] } } } Does this tell you anything? – keke Mar 11 '19 at 12:28

2 Answers2

3

Looks like the answer you mention is outdated.

Try this:

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

PythonShell.run('hello.py', null, function (err, results) {
  if (err) throw err;
  console.log('finished');
  console.log(results);
});

app.listen(4000);

Your second try is wrong in several places. You can try this way:

const express = require('express');
const app = express();
const spawn = require("child_process").spawn;

app.listen(3000, () => {
    console.log('server running on port 3000');
} );

app.get('/name', (req, res) => {

    const firstName = req.query['firstname'],
        lastName = req.query['lastname'];

    if (!firstName || !lastName) {
        res.status(401).send('missing-fields')
    }

    const process = spawn('python',["./hello.py", firstName, lastName] );

    let result = '';

    process.stdout.on('data', data => {
        result += data.toString();
    } );

    process.on('close', code => {
        res.send(result);
    })

} );
yeya
  • 1,968
  • 1
  • 21
  • 31
  • TypeError: ps.run is not a functionatObject – keke Mar 11 '19 at 12:55
  • So I tried it again, for the first time I didn't get an error. But the only thing that does happen is that the browser just loads without responding. I also tried to give it a file that doesn't appear in my directory to see what it does, and it acted exactly the same. Do you think it has something to do with the server not finding the Python file? – keke Mar 11 '19 at 14:01
  • You are not doing anything to provide the result. See the second option, only there you (and I) use the `res`. Don't just copy paste, try to understand. – yeya Mar 11 '19 at 14:06
0

i think this might help you with your first method :

const app = require('express')();
const ps = require('python-shell');

let options = {
  mode: 'text',
  pythonPath: '/usr/bin/python',
  pythonOptions: ['-u'], // get print results in real-time
  scriptPath: '/Users/apple/Desktop/xp',
  args: ['value1', 'value2']
};

ps.PythonShell.run('hello.py', options, function (err, results) {
   if (err) throw err;
   console.log('finished');
   console.log(results);
});

app.listen(4000);

Second Method code is working fine there is no error :

run : node script.js

it will run the server then open given below url on browser

http://localhost:3000/name?firstname=Mike&lastname=Will

sandeep
  • 13
  • 1
  • 5
  • server running on port 3000 events.js:173 throw er; // Unhandled 'error' event ^ Error: spawn python ENOENT at Process.ChildProcess._handle.onexit (internal/child_process.js:246:19) at onErrorNT (internal/child_process.js:421:16) at process.internalTickCallback (internal/process/next_tick.js:72:19) Emitted 'error' event at: at Process.ChildProcess._handle.onexit (internal/child_process.js:252:12) at onErrorNT (internal/child_process.js:421:16) at process.internalTickCallback (internal/process/next_tick.js:72:19) – keke Mar 11 '19 at 13:09
  • I tried what you said and this is my output. @sandeep – keke Mar 11 '19 at 13:10
  • for me it working fine and i am using node v11.6.0 and latest python-sell,expressjs package. – sandeep Mar 11 '19 at 13:13
  • I am also using Node v11.6.0 and the latest python shell, no luck ): – keke Mar 11 '19 at 14:02