Kết Nối Ứng Dụng Nodejs Với Python
Bài đăng này đã không được cập nhật trong 4 năm
Nodejs là một nền tảng phát triển web phổ biến hiện nay vì những lợi ích và sự tiện lợi mà nó đem lại. Nhưng có một vài điều mà nó còn chưa hỗ trợ như machine learning, deep learning và các thư viện về trí tuệ nhân tạo.Thật may Python hỗ trợ tất cả những thứ này và đôi khi là còn nhiều thứ khác mà nodejs không có. Mọi người sẽ tự hỏi là tại sao không sử dụng Django Framework của python để dựng những ứng dụng web có thể tích hợp machine learning và trí tuệ nhân tạo. Điều này có vẻ ổn đấy nếu khi ta dựng ứng dụng đó từ đầu. Nhưng nếu ứng dụng của chúng ta là Nodejs và nó đang chạy nhưng giờ ta lại muốn thêm machine learning vào thì sao. Không sao ta vẫn có thể kết nối Nodejs và Python như thường, bằng cách sử dụng child process module for Nodejs
.
Chúng ta sẽ có 3 cách để tương tác giữa python và nodejs nhưng trước tiên ta cần setup đã
Setup
-
Tạo một project Express đơn giản:
npm ini -y npm i express nodemon --save
Tạo file
server.js
đơn giản// Server.js var express = require(‘express’); var app = express(); app.listen(3000, function () { console.log(‘server running on port 3000’); })
Trong file
package.json
// package.json { "name": "node_integrate_python", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "nodemon server.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "nodemon": "^2.0.2" } }
Hãy thử chạy project trước khi tiếp tục
npm start
Kết quả như sau là được
[nodemon] 2.0.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node server.js` server running on port 3000
Tiếp đến ta cần một file chưa script xử lý python
process.py
:import sys print("Output from Python") print("First name: " + sys.argv[1]) print("Last name: " + sys.argv[2])
Cách 1: gọi Python script từ Node child process
-
Chúng ta cần sửa lại một chút file server của Express để nó gọi đến Python script child process
// server.js ... app.get('/name', callName); function callName(req, res) { var spawn = require('child_process').spawn; // E.g : http://localhost:3000/name?firstname=van&lastname=nghia var process = spawn('python', [ './process.py', req.query.firstname, req.query.lastname ]); process.stdout.on('data', function(data) { console.log(data.toString()); res.send(data.toString()); }); }
Hàm được sử dụng để tương tác giữa nodejs và python ở đây là child_process.spawn() theo như định nghĩa thì :
child_process.spawn(): This method helps us to spawn child process asynchronously.
hàm
child_process.spawn()
sẽ có các tham số như sauvar process = spawn('python', ['./process.py',arg1,arg2,.....]); - Tham số đầu tiên sẽ là file python script - theo sau sẽ là các arg tham số ta muốn truyền vào
Các tham số truyền vào sẽ được lấy ra theo đúng thứ tự
# process.py ... print("First name: " + sys.argv[1]) print("Last name: " + sys.argv[2])
Chạy ựng dụng lên và sau đó nhập đường link ví dụ là
http://localhost:3000/name?firstname=van&lastname=nghia
kết quả :trong console:
Cách 2: gọi Python script từ Node child process bằng cách sử dụng python-shell package
-
Cách này có thể hiểu là cách 1.1 vì thực ra ta vẫn sử dụng child process nhưng lúc này chúng ta sẽ sử dụng python-shell để gộp các chi tiết triển khai (cũng như cung cấp xử lý lỗi và các tiện ích khác bao gồm triển khai một messaging đơn giản để giao tiếp trực tiếp với một script đơn) .
Ta sẽ viết lại file server như sau:
// server.js app.get('/name', callName); function callName(req, res) { let { PythonShell } = require('python-shell'); var options = { args: [req.query.firstname, req.query.lastname] }; PythonShell.run('process.py', options, function(err, data) { if (err) res.send(err); console.log(data.toString()); res.send(data.toString()); }); }
Install package
python-shell
:npm i python-shell --save
chạy để kiểm tra ta sẽ có kết quả :
Cách 3 : sử dụng một message broker
-
Bây giờ chúng ta sẽ chạy ứng dụng Python và Node như các quy trình riêng biệt và sử dụng một message broker để giao tiếp giữa chúng . Ở đây chúng tôi sử dụng RabbitMQ, cùng với amqplib để tích hợp trong node và pika cho Python.
Thực hiện theo cài đặt RabbitMQ nếu bạn chưa cài, trên OSX bạn có thể chạy một cách đơn giản:
sudo apt update sudo apt -y install rabbitmq-server pip install pika npm install amqplib --save
Sau đó start
RabbitMQ
:sudo systemctl start rabbitmq-server.service
Bây giờ chúng ra sẽ chỉnh sửa file
server.js
. Sử dụng amqplib trong node để kết nối đến RabbitMQ instance đang chạy://server.js app.get('/name', callName); function callName(req, res) { var amqp = require('amqplib/callback_api'); var input = [req.query.firstname, req.query.lastname]; amqp.connect('amqp://localhost', function(err, conn) { conn.createChannel(function(err, ch) { var simulations = 'simulations'; ch.assertQueue(simulations, { durable: false }); var results = 'results'; ch.assertQueue(results, { durable: false }); ch.sendToQueue(simulations, Buffer.from(JSON.stringify(input))); ch.consume( results, function(msg) { console.log(msg.content.toString()); res.send(msg.content.toString()); }, { noAck: true } ); }); setTimeout(function() { conn.close(); }, 500); }); }
Chúng ta viết một trình xử lý message đơn giản bằng Python để xử lý các request messages, gọi process.py và publish response messages - message.py:
import pika import process import json connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.queue_declare(queue='simulations') channel.queue_declare(queue='results') def callback(ch, method, properties, body): requestParams = json.loads(body.decode('utf-8')) firstname = str(requestParams[0]) lastname = str(requestParams[1]) results = process.simulate(firstname, lastname) channel.basic_publish(exchange='', routing_key='results', body=json.dumps(results, ensure_ascii=False)) channel.basic_consume(queue='simulations', on_message_callback=callback, auto_ack=True) channel.start_consuming()
Tiếp đến Chúng ta cần thực hiện một số thay đổi nhỏ đối với process.py - bây giờ chúng ta sẽ truyền các tham số vào, thay vì sử dụng sys.argvs và expose ra một method mà chúng ta có thể gọi từ message.py:
# process.py import sys # print("Output from Python") # print("First name: " + sys.argv[1]) # print("Last name: " + sys.argv[2]) def simulate(firstname, lastname): results = { 'firstname': firstname, 'lastname': lastname } return results
Các bước để chạy thì đầu tiên ra sẽ run file
message.py
:python message.py
rồi mới chạy đến server node:
npm start
Kiểm tra kết quả
Kết Luận
Đây là một sự kết hợp đơn giản của Python và Node.js, điều này hữu ích cho các tình huống mà bạn muốn sử dụng các khả năng tính toàn của Python nhưng lại muốn tận dụng các lợi thế của ứng dụng Node.js. Mong rằng qua bài biết này các bạn có thể sử dụng và phát triển ứng dụng của mình tốt hơn từ những điều cơ bản này.
Source: https://github.com/ngovannghia1997kma/Node_integrate_Python
Nguồn :
https://medium.com/@HolmesLaurence/integrating-node-and-python-6b8454bfc272 https://www.geeksforgeeks.org/run-python-script-node-js-using-child-process-spawn-method/
All rights reserved