1
votes

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?

2
Try to console.log your ps variable to see what contains. - Jorge Fuentes González
Also search for ENOENT on Google. Google is your friend :P - Jorge Fuentes González
@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

2 Answers

2
votes

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);
    })

} );
0
votes

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