Snake In The JS Shadow: Run your python script in nodeJs

The cover image was sourced from here

Ever wondered if you could run a python function inside a nodejs code? I wondered also and I researched and got to see a module in nodejs child_process which allows you to run child processes. You may wonder what child processes are, well according to Wikipedia,

A child process in computing is a process created by another process. This technique pertains to multitasking operating systems and is sometimes called a subprocess or traditionally a subtask. There are two major procedures for creating a child process: the fork system call and the spawn.

I will attempt to walk you through how to run a non-blocking python script inside of your nodejs code.

Must-Haves

Obviously, you must have nodejs installed on your machine. After which you should import the fs module.
Also because I want to display the results in a browser, let's use express to serve it.

npm install express

Set up

Create two files, index.js and main.py, add the code below to your index.js file

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

In the main.py file, add the code below

print('Hello')

Main Implementation

In the index.js file, add the following

const pythonPromise = () => {
  return new Promise((resolve, reject) => {
    const python = spawn("python", ["./main.py"]);
    python.stdout.on("data", (data) => {
      resolve(data.toString());
    });

    python.stderr.on("data", (data) => {
      reject(data.toString());
    });
 });
};
app.get("/:name", async (req, res) => {
  const dataFromPython = await pythonPromise();
  res.send(dataFromPython + req.params.name);
});
app.listen(3200, () => console.log("App is running port 3200"));

The spawn function here takes two arguments, the first "python" which is the program we want to run, and "./main" which is the path to the python file we wish to run.
We all know nodejs is event-driven, the two events we are listening for are the python.stdout.on and python.stderr.on. The stderr is short for standard error, which occurs while attempting to run the python script while stdout is short for standard output, which is the return value from our script. The type of data returned is binary, which is why you need to call the toString() method to convert it to a string.

Start your server with node index.js and visit http://localhost:3200/yourName in your browser or postman to see the result.
hr.png
There will really be no need to use python scripts if we are not passing arguments to the python script, let's edit our main.py to have a function that takes arguments from your nodejs code. Replace with:

import sys
print('Hello ' + sys.argv[1] + ' your id is ' + sys.argv[2])

Also, we add more arguments to the spawn function and our index.js file should look like this below:

const pythonPromise = (data) => {
  return new Promise((resolve, reject) => {
    const python = spawn("python", ["./main.py", ...data]);

    python.stdout.on("data", (data) => {
      resolve(data.toString());
    });

    python.stderr.on("data", (data) => {
      reject(data.toString());
    });
  });
};

app.get("/:name/:id", async (req, res) => {
  const { name, id } = req.params;
  const dataFromPython = await pythonPromise([name, id]);
  res.send(dataFromPython);
});
app.listen(3200, () => console.log("App is running port 3200"));

You may be wondering what the sys module we imported in the main.py script is. According to geeksforgeeks,

The sys module provides functions and variables used to manipulate different parts of the Python runtime environment. This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.

And the indexes argv[1] and argv[2] are the parameters we wish to pass to the script. The first argument, argr[0] is the name of the file we are running the script from.
Start your server with node index.js and visit http://localhost:3200/yourName/anyId in your browser or postman to see the result.

This is a very basic example to expose you to the powers of the spawn method of the child_process module. There could be complex cases like passing JSON objects to your python script or receiving JSON data from the script, but this should get you started on the path to running python scripts in your nodejs applications. ✌🏻

14