Rufen Sie die Python-Funktion über JavaScript-Code auf

87

Ich möchte eine Python-Funktion aus JavaScript-Code aufrufen, da es in JavaScript keine Alternative gibt, um das zu tun, was ich will. Ist das möglich? Könnten Sie das folgende Snippet anpassen, um zu funktionieren?

JavaScript-Code:

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 enthält Funktionen mit erweiterten Bibliotheken, die in JavaScript nicht einfach zu schreiben sind:

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
quelle
9
Nein, Browser führen (zum Glück) keinen beliebigen Python-Code aus. Sie möchten das auf einem Server ausführen.
Fred Foo
Javascript läuft auf dem Client. Ich gehe davon aus, dass die Python auf dem Server läuft. Sie können eine Ajax-Anfrage an den Server senden. Es wird nicht schnell gehen.
John Dvorak
1
Senden Sie mit Ajax Text an ein Python-Skript auf Ihrem Server. Richten Sie das Skript so ein, dass Daten in einer einfach zu analysierenden (für js) Notation (wie JSON) zurückgegeben werden, und weisen Sie arrOfStrings im Success-Handler das Ergebnis zu.
Asad Saeeduddin
5
Sie können den offiziellen Python-Interpreter im Browser ausführen, indem Sie ihn mit clang und Emscripten kompilieren . Dies wurde schon früher gemacht.
1
@FredFoo, was eigentlich ein Glück wäre, wenn Browser kein ECMAScript ausführen würden (das aus eher zweifelhaften historischen Gründen als JavaScript bezeichnet wird). Was auch ein Glück wäre, wenn Browser eine sichere Teilmenge ausgeführt hätten (was jeder mit Ausführen meint) Alles in einem Browser, ungeachtet Ihres Strohmanns) von Python seit den 90er Jahren, damit wir uns nicht mit dem aktuellen Web-Chaos befassen müssen.
jdk1.0

Antworten:

58

Sie müssen lediglich eine Ajax-Anfrage an Ihren Pythoncode stellen. Sie können dies mit jquery http://api.jquery.com/jQuery.ajax/ tun oder einfach nur Javascript verwenden

$.ajax({
  type: "POST",
  url: "~/pythoncode.py",
  data: { param: text}
}).done(function( o ) {
   // do something
});
Salvador Dali
quelle
1
Es sieht interessant aus. Wo könnte der Aufruf von sein, processParagraph(text)damit die Rückgabewerte in der Variablen enden arrOfStrings?
Xralf
2
Ich []
führe
2
OK, wie ist es richtig? Meine Python-Datei enthält die richtige Funktion. Soll ich die Funktion in Python aufrufen und das Argument lautet sys.argv [1]?
Xralf
7
Vielen Dank für die Antwort, aber damit das Python-Skript ausgeführt werden kann, muss es von einem Webserver bereitgestellt werden, der es über CGI oder WSGI unterstützt. Könnten Sie bitte in Ihre Antwort aufnehmen, wie Sie dieses Problem lösen können?
Matteo
2
Oh, ich würde Ihre Antwort sehr gerne bearbeiten, wenn ich wüsste, wie das geht. Ich hatte gehofft, Sie könnten mir einen Rat geben, weil ich diesen Fehler erhalte XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourceund obwohl ich verstanden habe, was das Problem ist, weiß ich nicht, wie löse es. Irgendein nützlicher Zeiger? Vielen Dank. (Übrigens ... Schachhimmel scheint wirklich großartig! Ich werde es auf jeden Fall ausprobieren, gut, dass du ein süßes Mädchen in dein Profilbild aufgenommen hast;))
Matteo
26

Vom document.getElementsByTagNameIch denke , Sie JavaScript in einem Browser ausgeführt werden .

Die traditionelle Methode, um Funktionen für Javascript verfügbar zu machen, das im Browser ausgeführt wird, besteht darin, eine Remote-URL mit AJAX aufzurufen. Das X in AJAX ist für XML, aber heutzutage verwendet jeder JSON anstelle von XML.

Mit jQuery können Sie beispielsweise Folgendes tun:

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

Sie müssen einen Python-Webservice auf der Serverseite implementieren. Für einfache Webservices verwende ich gerne Flask .

Eine typische Implementierung sieht folgendermaßen aus:

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

Sie können Ironpython (Art Python.Net) im Browser mit laufen Silverlight , aber ich weiß nicht , ob NLTK für Ironpython zur Verfügung steht.

Paulo Scardine
quelle
9

Normalerweise erreichen Sie dies mit einer Ajax-Anforderung, die wie folgt aussieht

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

Sie können keine .py-Dateien aus JavaScript ohne das Python-Programm ausführen, wie Sie keine .txt-Dateien ohne einen Texteditor öffnen können. Mit Hilfe eines Web-API-Servers (IIS im folgenden Beispiel) wird das Ganze jedoch zu einem Atemzug.

  1. Installieren Sie Python und erstellen Sie eine Beispieldatei 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. Erstellen Sie eine Methode in Ihrem 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. Und jetzt zu Ihrem 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);
           }
        });
    }
    

Denken Sie daran, dass Ihre .py-Datei nicht auf dem Computer Ihres Benutzers ausgeführt wird, sondern auf dem Server.

Azakgaim
quelle
1

Kommunikation über Prozesse

Beispiel:

Python: Dieser Python-Codeblock sollte zufällige Temperaturen zurückgeben.

# 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): Hier müssen wir einen neuen untergeordneten Prozess erzeugen, um unseren Python-Code auszuführen und dann die gedruckte Ausgabe zu erhalten.

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