Wywołaj funkcję Pythona z kodu JavaScript


86

Chciałbym wywołać funkcję Pythona z kodu JavaScript, ponieważ w JavaScript nie ma alternatywy dla robienia tego, co chcę. czy to możliwe? Czy możesz dostosować poniższy fragment do działania?

Kod 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 zawiera funkcje korzystające z zaawansowanych bibliotek, które nie mają łatwego do napisania odpowiednika w 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)

8
Nie, przeglądarki (na szczęście) nie wykonają dowolnego kodu Pythona. Będziesz chciał uruchomić to na serwerze.
Fred Foo

JavaScript działa na kliencie. Zakładam, że Python działa na serwerze. Możesz wysłać żądanie AJAX do serwera. To nie będzie szybkie.
John Dvorak

1
Używając AJAX, wyślij tekst do skryptu Pythona na swoim serwerze. Skonfiguruj skrypt, aby zwracał dane w łatwej do przeanalizowania (dla js) notacji (jak JSON) i przypisz wynik do arrOfStrings w programie obsługi sukcesu.
Asad Saeeduddin

5
Możesz uruchomić oficjalnego interpretera Pythona w przeglądarce, kompilując go za pomocą clang i Emscripten . Zrobiono to już wcześniej.

1
@FredFoo, Całe szczęście byłoby, gdyby przeglądarki nie uruchamiały ECMAScript (który nazywa się JavaScript z dość wątpliwych powodów historycznych). Całe szczęście byłoby, gdyby przeglądarki korzystały z bezpiecznego podzbioru (co każdy ma na myśli, uruchamiając cokolwiek w przeglądarce, niezależnie od twojego słomnika) Pythona od lat 90., więc nie musielibyśmy mieć do czynienia z obecnym bałaganem w sieci.
jdk1.0

Odpowiedzi:


58

Wszystko, czego potrzebujesz, to wysłać żądanie Ajax do swojego pythoncode. Możesz to zrobić za pomocą jquery http://api.jquery.com/jQuery.ajax/ lub po prostu użyć javascript

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

1
To wygląda interesująco. Gdzie mogłoby być wywołanie of, processParagraph(text)aby zwracane wartości kończyły się na zmiennej arrOfStrings?
xralf

2
Uruchamiam ten kod w firebug, ale loguje[]
xralf

2
OK, więc jak to jest w porządku? Mój plik Pythona zawiera poprawną funkcję. Czy powinienem wywołać funkcję w Pythonie, a argumentem będzie sys.argv [1]?
xralf

7
Dzięki za odpowiedź, ale aby skrypt w Pythonie mógł zostać wykonany, musi zostać wdrożony przez serwer WWW, który obsługuje go za pośrednictwem CGI lub WSGI. Czy mógłbyś podać w swojej odpowiedzi, jak rozwiązać ten problem?
Matteo

2
Och, byłbym bardzo szczęśliwy edytując twoją odpowiedź, gdybym wiedział, jak to zrobić, miałem nadzieję, że możesz udzielić porady, ponieważ otrzymuję ten błąd XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourcei chociaż rozumiem, na czym polega problem, nie wiem jak rozwiązać. Jakieś przydatne wskazówki? Wielkie dzięki. (przy okazji ... chessheaven wydaje się naprawdę niesamowite! Spróbuję to na pewno, dobrze, że umieściłeś śliczną dziewczynę na swoim zdjęciu profilowym;))
Matteo

26

Od document.getElementsByTagNamechyba uruchamiasz javascript w przeglądarce.

Tradycyjnym sposobem udostępnienia funkcjonalności javascript działającemu w przeglądarce jest wywołanie zdalnego adresu URL za pomocą AJAX. X w AJAX dotyczy XML, ale obecnie wszyscy używają JSON zamiast XML.

Na przykład używając jQuery możesz zrobić coś takiego:

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

Będziesz musiał zaimplementować usługę sieciową w języku Python po stronie serwera. W przypadku prostych usług internetowych lubię używać Flaska .

Typowa implementacja wygląda następująco:

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

Możesz uruchomić IronPython (rodzaj Python.Net) w przeglądarce z Silverlight , ale nie wiem, czy NLTK jest dostępne dla IronPython.


9

Zwykle można to osiągnąć za pomocą żądania AJAX, które wygląda jak

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

Nie można uruchamiać plików .py z JavaScript bez programu w języku Python, tak jak nie można otwierać plików .txt bez edytora tekstu. Ale całość staje się oddechem dzięki pomocy Web API Server (IIS w przykładzie poniżej).

  1. Zainstaluj Pythona i utwórz przykładowy plik 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. Utwórz metodę na serwerze interfejsu API sieci 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. A teraz do Twojego 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);
           }
        });
    }
    

Pamiętaj, że plik .py nie będzie działał na komputerze użytkownika, ale na serwerze.


1

Komunikacja poprzez procesy

Przykład:

Python: ten blok kodu w języku Python powinien zwracać losowe temperatury.

# 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): Tutaj będziemy musieli stworzyć nowy proces potomny, aby uruchomić nasz kod w Pythonie, a następnie uzyskać wydruk.

// 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);
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.