Chiama la funzione Python dal codice JavaScript


87

Vorrei chiamare una funzione Python dal codice JavaScript, perché non esiste un'alternativa in JavaScript per fare ciò che voglio. È possibile? Potresti modificare lo snippet di seguito per farlo funzionare?

Codice JavaScript:

var tag = document.getElementsByTagName("p")[0];
text = tag.innerHTML;
// Here I would like to call the Python interpreter with Python function
arrOfStrings = openSomehowPythonInterpreter("~/pythoncode.py", "processParagraph(text)");

~/pythoncode.py contiene funzioni che utilizzano librerie avanzate che non hanno un equivalente facile da scrivere in JavaScript:

import nltk # is not in JavaScript
def processParagraph(text):
  ...
  nltk calls
  ...
  return lst # returns a list of strings (will be converted to JavaScript array)

9
No, i browser (fortunatamente) non eseguiranno codice Python arbitrario. Ti consigliamo di eseguirlo su un server.
Fred Foo

Javascript viene eseguito sul client. Presumo che Python venga eseguito sul server. Potresti inviare una richiesta ajax al server. Non sarà veloce.
John Dvorak

1
Utilizzando ajax, invia il testo a uno script Python sul tuo server. Configura lo script per restituire i dati in una notazione facile da analizzare (per js) (come JSON) e assegna il risultato a arrOfStrings nel gestore di successo.
Asad Saeeduddin

5
Puoi eseguire l'interprete Python ufficiale nel browser compilandolo usando clang ed Emscripten . Questo è già stato fatto.

1
@FredFoo, Ciò che sarebbe effettivamente fortunato è se i browser non eseguissero ECMAScript (che si chiama JavaScript per ragioni storiche piuttosto dubbie). Sarebbe anche fortunato se i browser avessero eseguito un sottoinsieme sicuro (che è ciò che chiunque intende eseguire eseguendo qualsiasi cosa in un browser, nonostante il tuo uomo di paglia) di Python dagli anni '90, quindi non dovremmo avere a che fare con l'attuale pasticcio web.
jdk1.0

Risposte:


58

Tutto ciò di cui hai bisogno è fare una richiesta ajax al tuo codice pitone. Puoi farlo con jquery http://api.jquery.com/jQuery.ajax/ o utilizzare solo javascript

$.ajax({
  type: "POST",
  url: "~/pythoncode.py",
  data: { param: text}
}).done(function( o ) {
   // do something
});

1
Sembra interessante. Dove potrebbe essere la chiamata di in processParagraph(text)modo che i valori restituiti finiscano nella variabile arrOfStrings?
xralf

2
Sto eseguendo questo codice in Firebug, ma registra[]
xralf

2
OK, allora com'è giusto? Il mio file Python contiene la funzione corretta. Devo chiamare la funzione in Python e l'argomento sarà sys.argv [1]?
xralf

7
Grazie per la risposta, ma affinché lo script python possa essere eseguito deve essere distribuito da un server web che lo supporti tramite CGI o WSGI. Potresti includere nella tua risposta come risolvere il problema?
Matteo

2
Oh, sarei molto felice di modificare la tua risposta se sapessi come farlo, speravo che tu potessi fornire qualche consiglio, perché ricevo questo errore XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourcee anche se ho capito qual è il problema non so come farlo risolvilo. Qualche suggerimento utile? Molte grazie. (btw ... chessheaven sembra davvero fantastico! Lo proverò di sicuro, per fortuna hai messo una ragazza carina nella tua immagine del profilo;))
Matteo

26

Dal document.getElementsByTagName Credo che si sta eseguendo il JavaScript in un browser.

Il modo tradizionale per esporre la funzionalità a javascript in esecuzione nel browser è chiamare un URL remoto utilizzando AJAX. La X in AJAX è per XML, ma oggigiorno tutti usano JSON invece di XML.

Ad esempio, usando jQuery puoi fare qualcosa come:

$.getJSON('http://example.com/your/webservice?param1=x&param2=y', 
    function(data, textStatus, jqXHR) {
        alert(data);
    }
)

Dovrai implementare un servizio web python sul lato server. Per servizi web semplici mi piace usare Flask .

Un'implementazione tipica è simile a:

@app.route("/your/webservice")
def my_webservice():
    return jsonify(result=some_function(**request.args)) 

Puoi eseguire IronPython (una specie di Python.Net) nel browser con Silverlight , ma non so se NLTK sia disponibile per IronPython.


9

In genere, lo faresti utilizzando una richiesta ajax simile a

var xhr = new XMLHttpRequest();
xhr.open("GET", "pythoncode.py?text=" + text, true);
xhr.responseType = "JSON";
xhr.onload = function(e) {
  var arrOfStrings = JSON.parse(xhr.response);
}
xhr.send();

4

Non puoi eseguire file .py da JavaScript senza il programma Python come non puoi aprire file .txt senza un editor di testo. Ma il tutto diventa un respiro con l'aiuto di un Web API Server (IIS nell'esempio sotto).

  1. Installa python e crea un file di esempio test.py

    import sys
    # print sys.argv[0] prints test.py
    # print sys.argv[1] prints your_var_1
    
    def hello():
        print "Hi" + " " + sys.argv[1]
    
    if __name__ == "__main__":
        hello()
    
  2. Crea un metodo nel tuo Web API Server

    [HttpGet]
    public string SayHi(string id)
    {
        string fileName = HostingEnvironment.MapPath("~/Pyphon") + "\\" + "test.py";          
    
        Process p = new Process();
        p.StartInfo = new ProcessStartInfo(@"C:\Python27\python.exe", fileName + " " + id)
        {
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };
        p.Start();
    
        return p.StandardOutput.ReadToEnd();                  
    }
    
  3. E ora per il tuo JavaScript:

    function processSayingHi() {          
       var your_param = 'abc';
       $.ajax({
           url: '/api/your_controller_name/SayHi/' + your_param,
           type: 'GET',
           success: function (response) {
               console.log(response);
           },
           error: function (error) {
               console.log(error);
           }
        });
    }
    

Ricorda che il tuo file .py non verrà eseguito sul computer dell'utente, ma sul server.


2

Comunicare attraverso i processi

Esempio:

Python: questo blocco di codice Python dovrebbe restituire temperature casuali.

# sensor.py

import random, time
while True:
    time.sleep(random.random() * 5)  # wait 0 to 5 seconds
    temperature = (random.random() * 20) - 5  # -5 to 15
    print(temperature, flush=True, end='')

Javascript (Nodejs): qui avremo bisogno di generare un nuovo processo figlio per eseguire il nostro codice python e quindi ottenere l'output stampato.

// temperature-listener.js

const { spawn } = require('child_process');
const temperatures = []; // Store readings

const sensor = spawn('python', ['sensor.py']);
sensor.stdout.on('data', function(data) {

    // convert Buffer object to Float
    temperatures.push(parseFloat(data));
    console.log(temperatures);
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.