How to Run a Python script from Node.js

Petros Koulianos 💀☠👽
The Startup
Published in
4 min readJan 16, 2020
Photo by Claudiu Pusuc on Unsplash

In this article, i will go through a sample app that can run a python script from Node.js, get data from the script and send it to the browser.

With little search at npm you will find several libs to run python scripts but i prefer to stick with node.js build in child_process .

1. Run a simple python script

Create a new folder :

mkdir nodePythonApp

Init a new node.js app:

cd nodePythonApp
npm init

Install express framework :

npm i express

Let’s write a simple python script:

script1.py
print('Hello from python')

Finally create the index.js file:

index.jsconst express = require('express')
const {spawn} = require('child_process');
const app = express()
const port = 3000
app.get('/', (req, res) => {

var dataToSend;
// spawn new child process to call the python script
const python = spawn('python', ['script1.py']);
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
dataToSend = data.toString();
});
// in close event we are sure that stream from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
// send data to browser
res.send(dataToSend)
});

})
app.listen(port, () => console.log(`Example app listening on port
${port}!`))

The above code, sets up a basic express app with one get router. Inside the get router, we spawn a new child_process with parameters:

spawn('python', ['script1.py']);

The first parameter is the program we want to call and the second is an array of strings that will use the python program. It is the same command if you wanted to write it in a shell to run the script1.py

python 'script1.py'

The first event we set is :

python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
dataToSend = data.toString();
});

This event is emitted when the script prints something in the console and returns a buffer that collects the output data. In order to convert the buffer data to a readable form, we use data.toString() method .

The last event we set is :

python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
// send data to browser
res.send(dataToSend)
});

The 'close' event is emitted when the stdio streams of a child process have been closed.

Inside this event, we are ready to send all the data from the python script to the browser.

Run the code :

node index.js

Now hit the browser at http://localhost:3000 and you will see the output of the python script.

2. Send parameters to python script

Most of the time python scripts require to pass a number of parameters. For that reason, i will show you a way to send as many parameters as you want.

Create a second python script (in the same directory with index.js file):

script2.pyimport sys
print('#Hello from python#')
print('First param:'+sys.argv[1]+'#')
print('Second param:'+sys.argv[2]+'#')

Add 2 params to your spawn method:

// spawn new child process to call the python script
const python = spawn(‘python’, [‘script2.py’,’node.js’,’python’]);

Save index.js file and run the code :

node index

Now hit the browser at http://localhost:3000 and you will see the output of the python script.

3. Get a JSON data set from python

Download a JSON file from: https://github.com/petranb2/Node_Python/blob/master/countries.json

Create a third python script (in the same directory with index.js file):

script3.pyimport jsonwith open('countries.json') as json_data:
for entry in json_data:
print(entry)

Change your index.js file a little bit :

const express = require('express')
const {spawn} = require('child_process');
const app = express()
const port = 3000
app.get('/', (req, res) => {var largeDataSet = [];
// spawn new child process to call the python script
const python = spawn('python', ['script3.py']);
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
largeDataSet.push(data);
});
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
// send data to browser
res.send(largeDataSet.join(""))
});

})
app.listen(port, () => console.log(`Example app listening on port
${port}!`))

Save index.js file and run the code :

npm index

Now hit the browser at http://localhost:3000 and you will see the output of the python script, what’s the difference with the other times.

Countries.json file has much more data to send, for that reason our first event ‘python.stdout.on’ will emit 2 times. For that reason, we use an array to append the data.

This was a sample app that shows how can node.js communicate with python, through a built-in child_process module.

You can download the sample app at Github https://github.com/petranb2/node_python.git

--

--

Petros Koulianos 💀☠👽
The Startup

Software Engineer 👽 | Building applications for health industry | Work with JavaScript, Typescript, PHP | My Newsletter📩 at petran.substack.com