নোড.জেএস থেকে পাইথন ফাংশনটি কীভাবে কল করা যায়


208

আমার একটি এক্সপ্রেস নোড.জেএস অ্যাপ্লিকেশন রয়েছে তবে পাইথনে ব্যবহার করার জন্য আমার কাছে একটি মেশিন লার্নিং অ্যালগরিদমও রয়েছে। মেশিন লার্নিং লাইব্রেরির শক্তি ব্যবহার করার জন্য আমার নোড.জেএস অ্যাপ্লিকেশন থেকে পাইথন ফাংশনগুলিকে কল করার কোনও উপায় আছে কি?


4
নোড-পাইথন । যদিও এটি নিজেই কখনও ব্যবহার করি না।
univerio

21
দুই বছর পরে, node-pythonএটি একটি পরিত্যক্ত প্রকল্প বলে মনে হচ্ছে।
imrek


জাভাস্ক্রিপ্টে অজগরকে সংকলন করতে এবং তারপরে এটি আহ্বান জানাতে github.com/QQuick/Transcrypt দেখুন
জোনাথন

উত্তর:


262

আমার জানা সবচেয়ে সহজ উপায় হ'ল "চাইল্ড_প্রসেস" প্যাকেজটি ব্যবহার করা যা নোডের সাথে প্যাকেজড আসে।

তারপরে আপনি এর মতো কিছু করতে পারেন:

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

তারপরে আপনাকে যা করতে হবে তা হ'ল import sysআপনি আপনার অজগর স্ক্রিপ্টের মধ্যে তা নিশ্চিত করে নিন এবং তারপরে আপনি arg1ব্যবহার করে sys.argv[1], arg2ব্যবহার sys.argv[2]এবং আরও কিছু অ্যাক্সেস করতে পারবেন ।

নোডে ডেটা ফেরত পাঠানোর জন্য পাইথন স্ক্রিপ্টে নিম্নলিখিতগুলি করুন:

print(dataToSendBack)
sys.stdout.flush()

এবং তারপরে নোড ব্যবহার করে ডেটা শুনতে পারে:

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

যেহেতু এটি স্পন ব্যবহার করে কোনও স্ক্রিপ্টে একাধিক আর্গুমেন্টগুলি পাস করার অনুমতি দেয়, আপনি একটি অজগর স্ক্রিপ্টটিকে পুনর্গঠন করতে পারেন যাতে আর্গুমেন্টগুলির মধ্যে একটি সিদ্ধান্ত নেয় যে কোন ফাংশনটি কল করতে হবে এবং অন্য আর্গুমেন্টটি সেই ফাংশনে পাস হবে ইত্যাদি etc.

আশা করি এটি পরিষ্কার ছিল। যদি কোনও কিছুর ব্যাখ্যা প্রয়োজন হয় তবে আমাকে জানান।


17
@ পাওলোএস.আব্রেবু: আমার সমস্যাটি execহ'ল এটি একটি স্ট্রিমের পরিবর্তে বাফারটি ফেরত দেয় এবং যদি আপনার ডেটা maxBufferসেটিংসের চেয়ে বেশি হয় , যা ডিফল্ট 200 কেবি হয়, আপনি একটি বাফারকে ছাড়িয়ে যান এবং আপনার প্রক্রিয়াটি মারা যায়। যেহেতু spawnস্ট্রিম ব্যবহার করে, এটি এর চেয়ে আরও নমনীয় exec
নেওয়ারফরেজওয়াই 2 কে

2
একটি ছোট্ট নোট, আপনি যদি নোড ব্যবহার করেন তবে আপনার সম্ভবত প্রক্রিয়াটি ব্যবহার করা উচিত নয়
অ্যালেক্সভিসগ্রাব

2
আমি কীভাবে বাহ্যিক পাইপ নির্ভরতা ইনস্টল করব? আমার কোনও প্রকল্পের জন্য নির্লজ্জ দরকার এবং এটি চালানো যায় না কারণ এটি ইনস্টল না করে।
javiergarval

2
@ জাভেইগারওয়াল এটি কোনও মন্তব্যের পরিবর্তে একটি নতুন প্রশ্ন হিসাবে আরও উপযুক্ত হবে।
নেভারফোরইটওয়াই

3
অজগর থেকে মুদ্রণ ব্যতীত অন্য কোন উপাত্ত ফেরত দেওয়া যায়? আমার অজগর স্ক্রিপ্ট প্রচুর লগ ডেটা আউটপুট করে এবং সম্ভবত এটি সমস্ত ডেটা ফ্লাশ করতে সমস্যা হয়
lxknvlk

111

উদাহরণ যারা পাইথন পটভূমি থেকে এসেছেন আর 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আপনার পাইথন স্ক্রিপ্টে মডিউল প্রয়োজন হয় না ।

নীচে ব্যবহার করে কার্য সম্পাদনের আরও একটি মডুলার উপায় 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!'))

8
আমি আশ্চর্য হয়েছি যে এটি আরও বেশি ভোট পেয়েছে না। @ নেভারফোরজিওয়াই 2 কে উত্তরটি ঠিক থাকলেও এই উত্তরে বন্দর শোনার সহ আরও বিশদ উদাহরণ রয়েছে, এবং কনস্ট এবং প্রতিশ্রুতির মতো আরও আধুনিক জেএস কনভেনশন সুন্দরভাবে ব্যবহার করেছেন।
মাইক উইলিয়ামসন

2
দুর্দান্ত উদাহরণ। পাইথন স্ক্রিপ্টে আমার কিছু ত্রুটি সনাক্ত করার জন্য প্রতিশ্রুতি দেওয়া ভাল ছিল।
htafoya

38

python-shellমডিউল দ্বারা extrabaconমৌলিক সঙ্গে Node.js থেকে পাইথন স্ক্রিপ্ট চালানোর জন্য একটি সহজ উপায়, কিন্তু দক্ষ আন্তঃ প্রসেস যোগাযোগ ব্যবস্থার এবং ভাল ত্রুটি পরিচালনা।

ইনস্টলেশন: npm install python-shell

একটি সাধারণ পাইথন স্ক্রিপ্ট চলছে:

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

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

যুক্তি এবং বিকল্পগুলি দিয়ে পাইথন স্ক্রিপ্ট চালানো হচ্ছে:

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 দেখুন


3
এই সমস্যাটি আমাকে এটি ব্যবহার থেকে বিরত
mhlavacka

1
যদি আপনি এই ত্রুটিটি পেয়ে যাচ্ছেন - টাইপ-এরর: পাইথনসেল.আরুন কোনও ফাংশন নয় তবে নিশ্চিত হয়ে নিন যে আপনি এটিকে ভার {পাইথনশেল like = এর মতো ('পাইথন-শেল') এর মতো আমদানি করেন;
মোহাম্মদ

4

আপনি এখন আরপিসি লাইব্রেরি ব্যবহার করতে পারেন যা পাইথন এবং জাভাস্ক্রিপ্ট যেমন জেরারপিসিকে সমর্থন করে

তাদের প্রথম পৃষ্ঠা থেকে:

নোড.জেএস ক্লায়েন্ট

var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");

client.invoke("hello", "RPC", function(error, res, more) {
    console.log(res);
});

পাইথন সার্ভার

import zerorpc

class HelloRPC(object):
    def hello(self, name):
        return "Hello, %s" % name

s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()

আপনি নোড এবং পাইথন উভয় দিকেই সকেট.আইও ব্যবহার করতে পারেন ।
ব্রুনো গাবুজোমু

3

পূর্ববর্তী উত্তরগুলির বেশিরভাগ অন ("ডেটা") এ প্রতিশ্রুতির সাফল্যকে ডাকে, এটি করার উপযুক্ত উপায় নয় কারণ আপনি প্রচুর ডেটা গ্রহণ করলে আপনি কেবল প্রথম অংশটি পাবেন। পরিবর্তে আপনাকে শেষ ইভেন্টে এটি করতে হবে।

const { spawn } = require('child_process');
const pythonDir = (__dirname + "/../pythonCode/"); // Path of python script folder
const python = pythonDir + "pythonEnv/bin/python"; // Path of the Python interpreter

/** remove warning that you don't care about */
function cleanWarning(error) {
    return error.replace(/Detector is not able to detect the language reliably.\n/g,"");
}

function callPython(scriptName, args) {
    return new Promise(function(success, reject) {
        const script = pythonDir + scriptName;
        const pyArgs = [script, JSON.stringify(args) ]
        const pyprog = spawn(python, pyArgs );
        let result = "";
        let resultError = "";
        pyprog.stdout.on('data', function(data) {
            result += data.toString();
        });

        pyprog.stderr.on('data', (data) => {
            resultError += cleanWarning(data.toString());
        });

        pyprog.stdout.on("end", function(){
            if(resultError == "") {
                success(JSON.parse(result));
            }else{
                console.error(`Python error, you can reproduce the error with: \n${python} ${script} ${pyArgs.join(" ")}`);
                const error = new Error(resultError);
                console.error(error);
                reject(resultError);
            }
        })
   });
}
module.exports.callPython = callPython;

কল করুন:

const pythonCaller = require("../core/pythonCaller");
const result = await pythonCaller.callPython("preprocessorSentiment.py", {"thekeyYouwant": value});

পাইথন:

try:
    argu = json.loads(sys.argv[1])
except:
    raise Exception("error while loading argument")

2

আমি নোড 10 এবং শিশু প্রক্রিয়াতে আছি 1.0.2। পাইথন থেকে প্রাপ্ত ডেটা বাইট অ্যারে এবং রূপান্তর করতে হয়। পাইথনে HTTP অনুরোধ করার আরও একটি দ্রুত উদাহরণ।

নোড

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

পিএস কোনও স্বীকৃত উদাহরণ নয় যেহেতু নোডের এইচটিপি মডিউলটি আমার করা কয়েকটি অনুরোধ লোড করে না


আমার নোডেজগুলিতে একটি সার্ভার ব্যাকএন্ড বিল্ড রয়েছে এবং আমার কাছে কয়েকটি মেশিন লার্নিং সম্পর্কিত পাইথন স্ক্রিপ্ট রয়েছে যা আমি যখনই আমার নোডেজ সার্ভারে অনুরোধটি গ্রহণ করি তখন নোডেজের মাধ্যমে শিশু প্রক্রিয়া ব্যবহার করে আমি স্পন ব্যবহার করি। যেমনটি এই থ্রেডে পরামর্শ দেওয়া হয়েছে। আমার প্রশ্নটি হল, এটি কি এটি করার সঠিক উপায় বা আমি আমার পাইথন স্ক্রিপ্টটি জেডএমকিউ ব্যবহার করে একটি ফ্ল্যাশ সার্ভিসের মতো কোনও বন্দরের সাথে আবদ্ধ করতে পারি এবং নোডেজ থেকে এই পরিষেবাটিতে একটি প্রতিশ্রুতি চালাতে পারি। ঠিক আমার অর্থটি কী, মেমরি সঞ্চয় এবং গতি সঞ্চয় পদ্ধতি কোন উপায়ে?
আসউইন

1
আপনি সম্ভবত অজগর জিনিস স্বাধীনভাবে চলতে চান। আপনি হার্ড কোড নির্ভরতা চান না, বিশেষত একটি মিল পরিষেবা হিসাবে আরও জটিল কিছু। আপনি যদি এই স্থাপত্যে অন্য টুকরো যোগ করতে চান? এমিলির সামনে ক্যাচিং লেয়ারের মতো, বা মিলি মডেলটিতে অতিরিক্ত পরামিতি যুক্ত করার উপায়? অজগর সার্ভারটি চালানোর জন্য এটি মেমরি, তবে আপনার সম্ভবত নমনীয়তা প্রয়োজন। পরে আপনি দুটি টুকরো দুটি সার্ভারে আলাদা করতে পারবেন
মিমি

তিনি জিজ্ঞাসা করেছিলেন যে তিনি কোনও ফাংশন কল করতে পারেন , এটি প্রশ্নের উত্তর দেয় না।
কে - এসও-তে বিষক্রিয়া বাড়ছে।

2
@ 1 মিমি 12 "কর্ল_মরিসন_আইস_এ_পিডেন্ট ()" হাহা ভালোবাসেন সাথী!
কে - এসও-তে বিষক্রিয়া বাড়ছে।

0

আপনি আপনার অজগরটি নিতে পারেন, এটি স্থানচ্যুত করতে পারেন, এবং তারপরে এটিকে জাভাস্ক্রিপ্ট হিসাবে কল করতে পারেন। আমি এটি সফলভাবে স্ক্রিপগুলির জন্য করেছি এবং এটি ব্রাউজারে একটি লা ব্রাইথন চালানোর জন্য পেয়েছি ।


0
/*eslint-env es6*/
/*global require*/
/*global console*/
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'); 
} ) 

app.get('/name', function(req, res) {

    console.log('Running');

    // 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=Levente
    var process = spawn('python',['apiTest.py', 
                        req.query.firstname]);

    // Takes stdout data from script which executed 
    // with arguments and send this data to res object
    var output = '';
    process.stdout.on('data', function(data) {

        console.log("Sending Info")
        res.end(data.toString('utf8'));
    });

    console.log(output);
}); 

এটি আমার পক্ষে কাজ করেছে। আপনার পাইথন.এক্সই এই কোড স্নিপেটের জন্য আপনাকে অবশ্যই পাথ ভেরিয়েবল যুক্ত করতে হবে। এছাড়াও, নিশ্চিত করুন যে আপনার অজগর স্ক্রিপ্টটি আপনার প্রকল্প ফোল্ডারে রয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.