Sling Academy
Home/Node.js/How to Call a Python Function in a Node.js App

How to Call a Python Function in a Node.js App

Last updated: December 28, 2023

A few approaches to executing Python code in your Node.js project.

1. Using Child Process Module

Solution Description: This solution involves using the built-in child_process module in Node.js to spawn a Python process and execute a Python script. The Node.js app can then capture and use the output from the Python script.

  1. Create a Python script (script.py) with the desired functions.
  2. In your Node.js application, use the child_process module to call the Python script and capture its output.
  3. Parse the output in Node.js as needed.
const { spawn } = require('child_process');

const pythonProcess = spawn('python', ['script.py', arg1, arg2]);

pythonProcess.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

pythonProcess.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

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

Pros:

  • Simple and does not require additional dependencies.
  • Can be used for one-time or low-frequency calls.

Cons:

  • Not suitable for high-performance applications due to the overhead of spawning new processes.
  • Data exchange is limited by string serialization.

2. Using a Socket-based Solution

Solution Description: In this approach, a Python script runs as a separate service, listening on a specific port. The Node.js app communicates with the Python service over sockets, sending and receiving messages.

  1. Set up a Python script that listens for network requests on a socket.
  2. In the Node.js app, establish a socket connection to the Python service to send and receive data.
  3. Implement a protocol for communication between the Node.js app and the Python script.
// Node.js side (client.js)
const net = require('net');
const client = new net.Socket();
client.connect(port, host, function() {
  console.log('Connected');
  client.write('Hello, server!');
});

client.on('data', function(data) {
  console.log('Received: ' + data);
  client.destroy(); // kill client after server's response
});

client.on('close', function() {
  console.log('Connection closed');
});

// Python side (server.py)
import socket

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((host, port))
serversocket.listen(5) # become a server socket

while True:
    clientsocket, address = serversocket.accept()
    data = clientsocket.recv(1024)
    clientsocket.send('Server response: ' + data)
    clientsocket.close()

Pros:

  • Allows for continuous and real-time communication between Node.js and Python.
  • Can be scaled to support multiple concurrent connections.

Cons:

  • More complex setup with additional handling of sockets and network programming.
  • Requires a network protocol between the services; may need to handle connection issues.

3. Using a Messaging Queue

Solution Description: A messaging queue such as RabbitMQ can be used for inter-process communication between a Node.js application and a Python script. This is suitable for distributed systems.

  1. Set up RabbitMQ and create a queue for messages.
  2. In the Node.js app, use a client library to send messages to the Python script via the queue.
  3. In the Python script, use a client library to receive messages from the queue and send back responses.
// Node.js side (sender.js)
const amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(error0, connection) {
  if (error0) {
    throw error0;
  }
  connection.createChannel(function(error1, channel) {
    if (error1) {
      throw error1;
    }
    const queue = 'task_queue';
    const msg = 'Hello Python!';

    channel.sendToQueue(queue, Buffer.from(msg));
    console.log(" [x] Sent '%s'", msg);
  });
});

// Python side (receiver.py)
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue')

def callback(ch, method, properties, body):
    print(f"Received {body}")

channel.basic_consume(queue='task_queue', on_message_callback=callback, auto_ack=True)

print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

Pros:

  • Robust communication method suitable for distributed and scalable applications.
  • Offers reliable message delivery even when receiver is temporarily unavailable.

Cons:

  • Requires setting up and maintaining a messaging queue server.
  • Additional complexity with asynchronous communication patterns.

Conclusion

Calling a Python function from a Node.js application can be achieved through various means. The right approach depends on the application’s requirements, the frequency of calls, and the necessary performance. Whether using child processes for simple scripting, socket-based real-time communication, or a robust messaging queue for distributed systems, each method has its benefits and trade-offs. Developers should consider these factors along with their existing system architecture to select the most appropriate integration approach.

Next Article: How to Deploy a Node.js App on Google App Engine

Previous Article: How to Run Multiple NPM Scripts Sequentially

Series: The First Steps to Node.js

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates