Node vs Python. Here's how you can use Spawn to run both in your project! 
Tags: python, node, beginners
Published: 2021-04-03 12:48:31

Hi everyone!

I wanted to share a solution on how you can create a single project which runs both Node and Python code.

# Node processes
As you most likely already know, it's possible for your computer to run multiple programs at once. Like you might have your browser open, your IDE running, whilst music is playing in the background. 

A process is an instance of a computer program. When you start a Node process it executes within a single thread. However, tasks that take a long time to complete, can block the main Node thread. In order to avoid this, and run multiple tasks at the same time, you can launch a child process.

# Use Node to launch a Python script with ChildProcess
If you wanted to use the command line to launch a python script called 'helper.py'. You'd use the command 'python', followed by an argument that represents the PATH to the file.

#### Command line
```
$ python helper.py
```

In Node, you can use `spawn()` to launch a child process. Spawn allows you to launch commands. The second argument of spawn, lets you pass arguments to the command. 

Below shows an example of using spawn to run a Python script called helper.py.

#### index.js
```javascript
const { spawn } = require('child_process');
spawn('python', ['helper.py']);
```

# Passing data between Node and Python

## Python sys Module

In Python, `sys.argv` is a list that contains arguments that were passed to the script. Below `sys.stdout.write()` is used to write to the standard output stream. Although `print()` does the same thing, `print()` also formats the output by adding a newline at the end (`\n`).

#### helper.py
```python
import sys

symbol, count = sys.argv[1], sys.argv[2]

pattern = symbol * int(count)

sys.stdout.write(pattern)
```
In Node, you can use spawn to pass data to the python script.  Therefore, if spawn is used like so `spawn('python', ['helper.py', 'text', 4])`, to access the string 'text' from within the Python script you can use `sys.argv[1]`. 

ChildProcess inherits from EventEmitter, which means that you can attach handlers to listen to 'error', 'close', and readable 'data' events. 

The data emitted is a Node Buffer, so for usability, you can use `toString()` to convert it to a string. 

Below shows an example in Node, of passing data from Node to the Python script 'helper.py', then back to Node so that the manipulated data can be logged in the console. 

#### index.js
```javascript
const { spawn } = require('child_process');
const python = spawn('python', ['helper.py', 'text', 4]);

python.stdout.on('data', (data) => {
  console.log('pattern: ', data.toString());
});

python.stderr.on('data', (data) => {
  console.error('err: ', data.toString());
});

python.on('error', (error) => {
  console.error('error: ', error.message);
});

python.on('close', (code) => {
  console.log('child process exited with code ', code);
});
```

Now if you were to run the above Node program called index.js in the command line using `node index.js`. You would see the following.

#### Command line
```
pattern:  texttexttexttext
child process exited with code  0
```

Thanks for reading!