web-dev-qa-db-fra.com

Comment appeler une fonction Python à partir de Node.js

J'ai une application Express Node.js, mais j'ai aussi un algorithme d'apprentissage automatique à utiliser en Python. Existe-t-il un moyen d'appeler les fonctions Python à partir de mon application Node.js pour utiliser toute la puissance des bibliothèques de machine learning?

139
Genjuro

Le moyen le plus simple que je connaisse est d'utiliser le paquetage "child_process" fourni avec le noeud.

Ensuite, vous pouvez faire quelque chose comme:

const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',["path/to/script.py", arg1, arg2, ...]);

Ensuite, tout ce que vous avez à faire est de vous assurer que vous avez import sys dans votre script python, puis vous pourrez accéder à arg1 en utilisant sys.argv[1], arg2 en utilisant sys.argv[2], etc.

Pour renvoyer des données au noeud, procédez comme suit dans le script python:

print(dataToSendBack)
sys.stdout.flush()

Et puis le noeud peut écouter les données en utilisant:

pythonProcess.stdout.on('data', (data) => {
    // Do something with the data returned from python script
});

Dans la mesure où cela permet de transmettre plusieurs arguments à un script à l'aide de spawn, vous pouvez restructurer un script python de sorte qu'un des arguments décide quelle fonction appeler, et que l'autre argument est passé à cette fonction, etc.

J'espère que c'était clair. Faites-moi savoir si quelque chose nécessite une clarification.

190
NeverForgetY2K

Exemple pour les personnes issues de Python et souhaitant intégrer leur modèle d'apprentissage automatique à l'application Node.js:

Il utilise le module principal 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!'))

Il ne nécessite pas de module sys dans votre script Python.

Vous trouverez ci-dessous un moyen plus modulaire d’effectuer la tâche à l’aide de 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!'))
75
Amit Upadhyay

Le module python-Shell de extrabacon constitue un moyen simple d'exécuter des scripts Python à partir de Node.js avec une communication interprocessus simple mais efficace, ainsi qu'une meilleure gestion des erreurs.

Installation: npm install python-Shell.

Exécution d'un simple script Python:

var PythonShell = require('python-Shell');

PythonShell.run('my_script.py', function (err) {
  if (err) throw err;
  console.log('finished');
});

Exécution d'un script Python avec arguments et options:

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);
});

Pour la documentation complète et le code source, consultez https://github.com/extrabacon/python-Shell

24
Soumik Rakshit

Le module de processus enfant de Node.js fournit une fonctionnalité permettant d’exécuter des scripts ou des commandes dans des langages autres que JavaScript (comme Python). Nous pouvons implémenter des algorithmes d'apprentissage machine, des algorithmes d'apprentissage approfondis et de nombreuses fonctionnalités fournies via une bibliothèque Python dans une application Node.js. Le module de processus enfant nous permet d'exécuter le script Python dans une application Node.js et de transférer des données en entrée/sortie dans/à partir d'un script Python.

child_process.spawn (): cette méthode nous aide à générer un processus enfant de manière asynchrone.

Créons un simple script Python qui prendra deux arguments en ligne de commande comme prénom et nom de famille, puis les affichera. Plus tard, nous exécuterons ce script à partir d’une application Node.js et afficherons le résultat dans la fenêtre du navigateur.

Script 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

Code serveur 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

Après avoir enregistré le script Python et le code de script du serveur, exécutez le code à partir de son dossier source à l'aide de la commande suivante:

node start.js
15
Rubin bhandari

Je suis sur le noeud 10 et le processus enfant 1.0.2. Les données de python sont un tableau d'octets et doivent être converties. Juste un autre exemple rapide de demande HTTP en python.

nœud

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()

p.s. pas un exemple artificiel puisque le module http du noeud ne charge pas quelques requêtes que je dois faire

1
1mike12

Vous pouvez prendre votre python, transpile , puis l'appeler comme s'il s'agissait de javascript. Je l'ai fait avec succès pour les screeps et l'ai même lancé dans le navigateur à la brython .

0
Jonathan