У меня есть приложение Express Node.js, но у меня также есть алгоритм машинного обучения для использования в Python. Есть ли способ вызвать функции Python из моего приложения Node.js, чтобы использовать возможности библиотек машинного обучения?
Как вызвать функцию Python из Node.js
Ответ 1
Самый простой способ, который я знаю, это использовать пакет child_process, который поставляется вместе с узлом.
Тогда вы можете сделать что-то вроде:
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',["path/to/script.py", arg1, arg2, ...]);
Тогда все, что вам нужно сделать, это убедиться, что вы import sys
в свой скрипт на python, а затем вы можете получить доступ к arg1
с помощью sys.argv[1]
, arg2
с помощью sys.argv[2]
и так далее.
Чтобы отправить данные обратно на узел, просто сделайте следующее в скрипте python:
print(dataToSendBack)
sys.stdout.flush()
И тогда узел может прослушивать данные, используя:
pythonProcess.stdout.on('data', (data) => {
// Do something with the data returned from python script
});
Поскольку это позволяет нескольким аргументам передаваться в скрипт с помощью spawn, вы можете реструктурировать скрипт python так, чтобы один из аргументов решал, какую функцию вызывать, а другой аргумент передавался этой функции и т.д.
Надеюсь, это было ясно. Дайте мне знать, если что-то нужно уточнить.
Ответ 2
Пример для людей, которые имеют опыт работы с Python и хотят интегрировать свою модель машинного обучения в приложение Node.js:
Он использует основной модуль child_process
:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
const { spawn } = require('child_process');
const pyProg = spawn('python', ['./../pypy.py']);
pyProg.stdout.on('data', function(data) {
console.log(data.toString());
res.write(data);
res.end('end');
});
})
app.listen(4000, () => console.log('Application listening on port 4000!'))
Для этого не требуется модуль sys
в вашем скрипте Python.
Ниже приведен более модульный способ выполнения задачи с использованием Promise
:
const express = require('express')
const app = express()
let runPy = new Promise(function(success, nosuccess) {
const { spawn } = require('child_process');
const pyprog = spawn('python', ['./../pypy.py']);
pyprog.stdout.on('data', function(data) {
success(data);
});
pyprog.stderr.on('data', (data) => {
nosuccess(data);
});
});
app.get('/', (req, res) => {
res.write('welcome\n');
runPy.then(function(fromRunpy) {
console.log(fromRunpy.toString());
res.end(fromRunpy);
});
})
app.listen(4000, () => console.log('Application listening on port 4000!'))
Ответ 3
Модуль python-shell
от extrabacon
- это простой способ запуска скриптов Python из Node.js с базовым, но эффективным межпроцессным взаимодействием и лучшей обработкой ошибок.
Установка: npm install python-shell
.
Запуск простого скрипта Python:
var PythonShell = require('python-shell');
PythonShell.run('my_script.py', function (err) {
if (err) throw err;
console.log('finished');
});
Запуск скрипта Python с аргументами и параметрами:
var PythonShell = require('python-shell');
var options = {
mode: 'text',
pythonPath: 'path/to/python',
pythonOptions: ['-u'],
scriptPath: 'path/to/my/scripts',
args: ['value1', 'value2', 'value3']
};
PythonShell.run('my_script.py', options, function (err, results) {
if (err)
throw err;
// Results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
Для полной документации и исходного кода, проверьте https://github.com/extrabacon/python-shell
Ответ 4
Модуль дочернего процесса для Node.js предоставляет функциональные возможности для запуска сценариев или команд на языках, отличных от JavaScript (например, Python). Мы можем реализовать алгоритмы машинного обучения, алгоритмы глубокого обучения и многие функции, предоставляемые через библиотеку Python, в приложение Node.js. Дочерний модуль процесса позволяет нам запускать скрипт Python в приложении Node.js и передавать/выводить данные в/из скрипта Python.
child_process.spawn(): Этот метод помогает нам асинхронно порождать дочерний процесс.
Давайте создадим простой скрипт Python, который будет принимать два аргумента командной строки в качестве имени и фамилии, а затем отображать их. Позже хорошо запустите этот скрипт из приложения Node.js и отобразите вывод в окне браузера.
Скрипт Python:
import sys
# Takes first name and last name via command
# line arguments and then display them
print("Output from Python")
print("First name: " + sys.argv[1])
print("Last name: " + sys.argv[2])
# Save the script as hello.py
Код сервера Node.js:
// Import Express.js JavaScript module into the application
// and creates its variable.
var express = require('express');
var app = express();
// Creates a server which runs on port 3000 and
// can be accessed through localhost:3000
app.listen(3000, function() {
console.log('server running on port 3000');
} )
// Function callName() is executed whenever
// the URL is of the form localhost:3000/name
app.get('/name', callName);
function callName(req, res) {
// Use child_process.spawn method from
// child_process module and assign it
// to variable spawn
var spawn = require("child_process").spawn;
// Parameters passed in spawn -
// 1. type_of_script
// 2. List containing Path of the script
// and arguments for the script
// E.g.: http://localhost:3000/name?firstname=Mike&lastname=Will
// So, first name = Mike and last name = Will
var process = spawn('python',["./hello.py",
req.query.firstname,
req.query.lastname] );
// Takes stdout data from script which executed
// with arguments and send this data to res object
process.stdout.on('data', function(data) {
res.send(data.toString());
} )
}
// Save code as start.js
После сохранения сценария Python и кода серверного сценария запустите код из его исходной папки с помощью следующей команды:
node start.js
Ответ 5
Я нахожусь на узле 10 и дочерний процесс 1.0.2
. Данные из python являются байтовым массивом и должны быть преобразованы. Еще один быстрый пример выполнения http-запроса на python.
узел
const process = spawn("python", ["services/request.py", "https://www.google.com"])
return new Promise((resolve, reject) =>{
process.stdout.on("data", data =>{
resolve(data.toString()); // <------------ by default converts to utf-8
})
process.stderr.on("data", reject)
})
request.py
import urllib.request
import sys
def karl_morrison_is_a_pedant():
response = urllib.request.urlopen(sys.argv[1])
html = response.read()
print(html)
sys.stdout.flush()
karl_morrison_is_a_pedant()
ps не надуманный пример, так как модуль http узла не загружает несколько запросов, которые мне нужно сделать
Ответ 6
Вы можете взять свой питон, перенести его, а затем назвать так, как если бы это был JavaScript. Я сделал это успешно для screeps и даже заставил его работать в браузере по- своему.