Llamar a la función Python desde el código JavaScript

85

Me gustaría llamar a una función de Python desde el código JavaScript, porque no hay una alternativa en JavaScript para hacer lo que quiero. es posible? ¿Podría ajustar el siguiente fragmento para que funcione?

Código 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 funciones que utilizan bibliotecas avanzadas que no tienen un equivalente fácil de escribir en 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)
xralf
fuente
8
No, los navegadores (afortunadamente) no ejecutarán código Python arbitrario. Querrá ejecutar eso en un servidor.
Fred Foo
Javascript se ejecuta en el cliente. Supongo que Python se ejecuta en el servidor. Puede enviar una solicitud ajax al servidor. No será rápido.
John Dvorak
1
Usando ajax, envíe texto a una secuencia de comandos de Python en su servidor. Configure el script para devolver datos en una notación fácil de analizar (para js) (como JSON) y asigne el resultado a arrOfStrings en el controlador de éxito.
Asad Saeeduddin
5
Puede ejecutar el intérprete oficial de Python en el navegador compilándolo usando clang y Emscripten . Esto se ha hecho antes.
1
@FredFoo, lo que en realidad sería una suerte es si los navegadores no ejecutaran ECMAScript (que se llama JavaScript por razones históricas bastante dudosas). Lo que también sería afortunado es si los navegadores hubieran estado ejecutando un subconjunto seguro (que es lo que cualquiera quiere decir con ejecutar cualquier cosa en un navegador, a pesar de su hombre de paja) de Python desde los años 90, por lo que no tendríamos que lidiar con el lío web actual.
jdk1.0

Respuestas:

58

Todo lo que necesita es hacer una solicitud ajax a su pythoncode. Puede hacer esto con jquery http://api.jquery.com/jQuery.ajax/ , o usar solo javascript

$.ajax({
  type: "POST",
  url: "~/pythoncode.py",
  data: { param: text}
}).done(function( o ) {
   // do something
});
Salvador Dalí
fuente
1
Se ve interesante. ¿Dónde podría estar la llamada de processParagraph(text)para que los valores devueltos terminen en la variable arrOfStrings?
xralf
2
Estoy ejecutando este código en Firebug, pero se registra[]
xralf
2
Bien, entonces, ¿cómo está bien? Mi archivo Python contiene la función correcta. ¿Debo llamar a la función en Python y el argumento será sys.argv [1]?
xralf
7
Gracias por la respuesta, pero para que el script de Python se ejecute tiene que ser implementado por un servidor web que lo admita a través de CGI o WSGI. ¿Podría incluir en su respuesta cómo resolver ese problema?
Matteo
2
Oh, estaría muy feliz de editar tu respuesta si supiera cómo hacer eso, esperaba que pudieras dar algún consejo, porque recibo este error XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourcey, aunque entendí cuál es el problema, no sé cómo resuélvelo. ¿Algún puntero útil? Muchas gracias. (por cierto ... ¡Chessheaven parece realmente increíble! Lo probaré con seguridad, es bueno que hayas puesto a una linda chica en tu foto de perfil;))
Matteo
26

Del document.getElementsByTagNameCreo que se está ejecutando el código JavaScript en un navegador.

La forma tradicional de exponer la funcionalidad a javascript que se ejecuta en el navegador es llamar a una URL remota usando AJAX. La X en AJAX es para XML, pero hoy en día todo el mundo usa JSON en lugar de XML.

Por ejemplo, usando jQuery puede hacer algo como:

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

Deberá implementar un servicio web Python en el lado del servidor. Para servicios web sencillos, me gusta usar Flask .

Una implementación típica se ve así:

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

Puede ejecutar IronPython (una especie de Python.Net) en el navegador con silverlight , pero no sé si NLTK está disponible para IronPython.

Paulo Scardine
fuente
9

Por lo general, lograría esto usando una solicitud ajax que se parece 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();
Asad Saeeduddin
fuente
4

No puede ejecutar archivos .py desde JavaScript sin el programa Python como no puede abrir archivos .txt sin un editor de texto. Pero todo se convierte en un soplo con la ayuda de un servidor API web (IIS en el ejemplo siguiente).

  1. Instale Python y cree un archivo de muestra 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. Cree un método en su servidor Web API

    [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. Y ahora para tu 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);
           }
        });
    }
    

Recuerde que su archivo .py no se ejecutará en la computadora de su usuario, sino en el servidor.

azakgaim
fuente
1

Comunicarse a través de procesos

Ejemplo:

Python: este bloque de código de Python debería devolver temperaturas aleatorias.

# 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): aquí necesitaremos generar un nuevo proceso hijo para ejecutar nuestro código Python y luego obtener la salida impresa.

// 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);
});
Michael Obasi
fuente