Chame a função Python do código JavaScript

87

Eu gostaria de chamar uma função Python do código JavaScript, porque não há uma alternativa em JavaScript para fazer o que eu quero. Isso é possível? Você poderia ajustar o snippet abaixo para funcionar?

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 contém funções que usam bibliotecas avançadas que não têm um equivalente fácil de escrever em 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
fonte
9
Não, os navegadores (felizmente) não executam código Python arbitrário. Você vai querer executar isso em um servidor.
Fred Foo
Javascript é executado no cliente. Presumo que o python seja executado no servidor. Você pode enviar uma solicitação ajax para o servidor. Não vai ser rápido.
John Dvorak
1
Usando ajax, envie texto para um script Python em seu servidor. Configure o script para retornar dados em uma notação fácil de analisar (para js) (como JSON) e atribua o resultado a arrOfStrings no manipulador de sucesso.
Asad Saeeduddin 01 de
5
Você pode executar o interpretador oficial do Python no navegador, compilando-o usando clang e Emscripten . Isso já foi feito antes.
1
@FredFoo, o que seria realmente uma sorte é se os navegadores não executassem ECMAScript (que é chamado de JavaScript por razões históricas bastante duvidosas). O que também seria uma sorte é se os navegadores estivessem executando um subconjunto seguro (que é o que qualquer um entende por qualquer coisa em um navegador, apesar do seu espantalho) de Python desde os anos 90, então não teríamos que lidar com a atual bagunça da web.
jdk1.0

Respostas:

58

Tudo que você precisa é fazer uma solicitação ajax para seu código python. Você pode fazer isso com jquery http://api.jquery.com/jQuery.ajax/ ou usar apenas javascript

$.ajax({
  type: "POST",
  url: "~/pythoncode.py",
  data: { param: text}
}).done(function( o ) {
   // do something
});
Salvador Dalí
fonte
1
Parece interessante. Onde poderia estar a chamada de processParagraph(text)para que os valores de retorno terminassem na variável arrOfStrings?
xralf 01 de
2
Estou executando este código no firebug, mas ele registra[]
xralf 01 de
2
OK, então como está certo? Meu arquivo Python contém a função correta. Devo chamar a função em Python e o argumento será sys.argv [1]?
xralf 01 de
7
Obrigado pela resposta, mas para que o script python seja executado, ele deve ser implementado por um servidor web que o suporte via CGI ou WSGI. Você poderia incluir em sua resposta como resolver esse problema?
Matteo
2
Eu ficaria muito feliz em editar sua resposta se eu soubesse como fazer isso, eu esperava que você pudesse fornecer alguns conselhos, porque estou recebendo este erro XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourcee mesmo sabendo qual é o problema, não sei como resolva isso. Qualquer ponteiro útil? Muito obrigado. (aliás ... chessheaven parece realmente incrível! Vou tentar com certeza, que bom que você colocou uma garota bonita em sua foto de perfil;))
Matteo
26

Do document.getElementsByTagNameque eu acho que você está rodando o JavaScript em um navegador.

A maneira tradicional de expor a funcionalidade do javascript em execução no navegador é chamar uma URL remota usando AJAX. OX em AJAX é para XML, mas hoje em dia todo mundo usa JSON em vez de XML.

Por exemplo, usando jQuery, você pode fazer algo como:

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

Você precisará implementar um serviço da web python no lado do servidor. Para serviços da web simples, gosto de usar o Flask .

Uma implementação típica se parece com:

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

Você pode executar IronPython (uma espécie de Python.Net) no navegador com silverlight , mas não sei se NLTK está disponível para IronPython.

Paulo Scardine
fonte
9

Normalmente, você faria isso usando uma solicitação ajax que se parece com

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
fonte
4

Você não pode executar arquivos .py em JavaScript sem o programa Python, da mesma forma que não pode abrir arquivos .txt sem um editor de texto. Mas tudo se transforma em um fôlego com a ajuda de um Web API Server (IIS no exemplo abaixo).

  1. Instale o python e crie um arquivo de amostra 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. Crie um método em seu servidor de API da Web

    [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 agora para o seu 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);
           }
        });
    }
    

Lembre-se de que seu arquivo .py não será executado no computador do usuário, mas sim no servidor.

azakgaim
fonte
2

Comunicação por meio de processos

Exemplo:

Python: este bloco de código Python deve retornar temperaturas aleatórias.

# 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): aqui, precisaremos gerar um novo processo filho para executar nosso código Python e, em seguida, obter a saída impressa.

// 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
fonte