Child process exit with code 1 while running python script from nodejs - python

const express = require('express')
const {spawn} = require('child_process');
const app = express()
const port = 8000
app.get('/', (req, res) => {
var dataToSend;
const python = spawn('python', ['script.py']);
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
dataToSend = data.toString();
});
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
res.send(dataToSend)
});
})
app.listen(port, () => console.log(`Example app listening on port
${port}!`))
This is my index.js file and when I try to run a python script from it, it works only for code that is written before import part in python script. When i run python script individually it runs perfect but not from js file. why ?

Related

Vanilla Nodejs trigger Python script in new terminal

I want Nodejs to run a Python script in a new terminal.
I have a python script named test.py which simply does print('Hello World')
However, when I enter localhost:8080/python_run/ in my browser, I do not know if the script is run.
I can know the output using python.stdout.on('data', (data) => {console.log(`stdout: ${data}`);})
but I want to be able to monitor a large complex python script running which would give many print statements throughout.
I want it to display in a separate terminal instead of seeing only the std.out in the nodejs terminal.
I also wish to only implement these using vanilla nodejs.
The spawn child process of nodejs does not seem to let me run in a separate terminal.
How can I trigger a long complex and probably resource intensive Python script to run with the nodejs server as long as it receives a request (GET request of the url in this case)? If possible I'd also want the Python script to communicate back to the nodejs server once the Python script has finished running, to trigger some change of display of a website.
My current code
const {parse} = require('querystring');
const http = require('http');
const path = require('path');
const fs = require('fs');
var url = require("url");
const {spawn} = require('child_process');
const spawn1 = require('child_process').exec;
const requestHandler = (req, res) => {
fs.readFile("index_noexp.html",(err, data) => {
if(!err) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(data);
}
});
if (/python_run/i.test(req.url)) {
console.log('Now running the dangerous python script');
try {
const { spawn } = require('node:child_process');
var python = spawn('python', ['/Users/damian/nodetest/test.py']);
// var python = spawn1('python', [__dirname + '/test.py']);
python.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
})
} catch (error) {
console.error(error);
} finally {
console.log('Not sure what happened');
}
}
const server = http.createServer(requestHandler);
server.listen(8080);

TypeError: child_process_1.spawn is not a function

I'm using Electron + React JS as frontend which in turn will communicate the backend program(Python). I've looked for solutions and came up with something called python-shell library. This library helps to communicate or call out the backend.
upload.js
const handleSubmit = (e) => {
e.preventDefault()
console.log(file)
var pyShell = require('python-shell');
let options = {
mode: 'text',
args: [file]
};
pyShell.PythonShell.run('./py/backend.py', (err, results) => {
if (err) throw err;
console.log('results: ', results);
results.textContent = results[0];
});
}
backend.py
import sys
print('Hello from Python!')
sys.stdout.flush()
It shows me an error TypeError: child_process_1.spawn is not a function, and it shows the error location of index.ts(But there is no index.ts file in my entire directory).

How to run python environment through node.js

I am developing a web application that will use python model.I have created environment for python model as well.But the problem i am facing is i have no idea how to execute that python environment through node js because i am using node.js at backend.
you can run python virtual environment inside nodejs, you need call python environment from bin directory where you install python virtual environment, and then you can use child_process for run python code inside nodejs, see this example:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
const { spawn } = require('child_process');
const pyProg = spawn('~/py3env/bin/python', ['test.py']);
pyProg.stdout.on('data', function(data) {
console.log(data.toString());
res.write(data);
res.end('end');
});
})
app.listen(3000, () => console.log('listening on port 3000'))
even you can excecute command line with shelljs, and in this moment you can run pm2: see this:
const shell = require('shelljs');
shell.exec('pm2 start test.py --interpreter=./py3env/bin/python', function(code, output) {
console.log('Exit code:', code);
console.log('Program output:', output);
});
After you setting your python virtual enironment, You can use PythonShell in node js
Firstly install PythonShell to your project by this command
npm install python-shell --save
then you can call python script in your js file by the following
const path = require('path');
const { PythonShell } = require("python-shell");
// this is your current folder
const py_path = path.join(__dirname, '');
// this is your folder with python environment in it
const python_exe_path = path.join(__dirname, 'python_env/scripts/python.exe');
// then create your python shell options
const py_shell_options = {
mode: 'text',
pythonPath: python_exe_path,
pythonOptions: ['-u'], // get print results in real-time
scriptPath: py_path
// args: ['value1', 'value2', 'value3']
};
// now you can initialize your shell and ready to use it
const pyshell = new PythonShell('py_scripts/my_script.py', py_shell_options);
// sends a message to the Python script via stdin
pyshell.send('hello');
pyshell.on('message', function (message) {
// received a message sent from the Python script (a simple "print" statement)
console.log(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');
});
That it, please read more about PythonShell from the official site

Calling python script with node js express server

With below code I have created a HTTP server on port 3000 and have added some get parameters. I want to invoke a python script with this express.js server code such that when I hit localhost:3000/key1/abc/key2/234 python script will get invoked. I've my python script ready which takes input args as sys.argv. Please suggest how to call python script with this code so that it will take value1 and value 2 as input arguments and return json.
var express = require('express');
var app = express();
app.get('/key1/:value1/key2/:value2',function(req,res)
{
console.log(req.params);
var value1 = req.params.value1;
var value2 = req.params.value2;
res.send(req.params);
});
app.listen(3000,function()
{
console.log("Server listening on port 3000");
});
To run a Python script from Node.js would require spawning a new process.
You can do that with child_process.
You would run python as the executable and give your script name as the first argument.
Here is an example based on the documentation linked above:
const spawn = require('child_process').spawn;
const ls = spawn('python', ['script.py', 'arg1', 'arg2']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
If you want to execute it with params
const scriptExecution = spawn(pythonExecutable, ["my_Script.py", "Argument 1","Argument 2"]);

redis with nodejs+socketio and python, message event fired twice?

I've set a nodejs server along with simple python script with redis-py.
I have this on my nodejs server:
var http = require('http');
var server=http.createServer(onRequest).listen(3000);
var io = require('socket.io')(server);
var redis = require('redis');
var fs= require('fs');
var sub = redis.createClient();
sub.subscribe('channel');
function onRequest(req,res){
var index;
fs.readFile('./index.html', function (err, data) {
if (err) {
throw err;
}
index = data;
res.writeHead(200,{'Content-Type':'text/html'});
res.write(index);
res.end();
});
};
var sockets=[];
io.on('connection', function(socket){
console.log('a user connected');
sockets.push(socket);
console.log(sockets.length);
sub.on('message', function(channel, message){
console.log(message);
sockets[0].emit('chat message',message);
});
io.emit('chat message', "enter nickname");
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
This is just a simple test where I've tried to find out why my messages are sent multiple times.
I've figured that sub.on('message') is fired twice for each message that I send from python. Why?
The python code is pretty simple:
import redis
r=redis.StrictRedis()
pubsub=r.pubsub()
r.publish('channel',"HHHHHHH")

Categories