Snake In The JS Shadow: Run your python script in nodeJs
Tags: javascript, python, webdev, node
Published: 2021-09-04 23:29:54

<sub><sup>The cover image was sourced from [here](https://pythonsway.it/javascript-python/)</sup></sub>

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')
```
![hr.png](https://steemitimages.com/DQmP4WCzAeZaZpjjkDDy2ouW6STJkxbr7gf2SPdgA3Hrziu/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"));
```

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](https://steemitimages.com/DQmP4WCzAeZaZpjjkDDy2ouW6STJkxbr7gf2SPdgA3Hrziu/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](https://www.geeksforgeeks.org/how-to-use-sys-argv-in-python/),
> 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](https://steemitimages.com/DQmP4WCzAeZaZpjjkDDy2ouW6STJkxbr7gf2SPdgA3Hrziu/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. ✌🏻