DEV Community

Cover image for Snake In The JS Shadow: Run your python script in nodeJs
Ademola Babatunde
Ademola Babatunde

Posted on

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();
Enter fullscreen mode Exit fullscreen mode

In the main.py file, add the code below

print('Hello')
Enter fullscreen mode Exit fullscreen mode

hr.png

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"));
Enter fullscreen mode Exit fullscreen mode

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])
Enter fullscreen mode Exit fullscreen mode

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"));
Enter fullscreen mode Exit fullscreen mode

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.

hr.png

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. ✌🏻

Discussion (4)

Collapse
bryandev profile image
Ikenna-Alfred Chimereze

Interesting stuff

Collapse
iamwizzdom profile image
Wisdom Emenike

Good read. 👍🏽

Collapse
thekharleeci profile image
TheKharleeci

Great article. Really insightful. Thanks for sharing

Collapse
gabrielfortune5 profile image
FortuneTech, web developer

Interesting stuff. Nice one bro