5 Stimmen

Streaming des Zustands eines Python-Skripts auf eine Website

Ich habe einen einfachen Arbeitsablauf [Step 0]->[1]->[2]->...->[Step N] . Das Masterprogramm kennt den Schritt (Zustand), in dem es sich gerade befindet.

Ich möchte dies in Echtzeit auf eine Website (im lokalen Netz) streamen, so dass meine Kollegen, wenn sie z. B. die Website öffnen, die Daten in Echtzeit übertragen können, http://thecomputer:8000 können sie eine Echtzeit-Darstellung des aktuellen Stands unseres Arbeitsablaufs mit allen relevanten Details sehen.

Ich habe darüber nachgedacht, den Zustand des Skripts in eine StringIO Objekt (Streaming zu ihm) und verwenden Javascript um den Browser zu aktualisieren, aber ich habe ehrlich gesagt keine Ahnung, wie man das macht.

Haben Sie einen Rat?

1voto

Daenyth Punkte 33328

Sie könnten das Python-Skript eine Xml-Datei schreiben lassen, die Sie mit einer Ajax-Anfrage in Ihrer Webseite erhalten, und die Statusinformationen daraus abrufen.

0 Stimmen

Aber wie kann man eine XML-Datei aktualisieren, ohne sie jedes Mal neu zu schreiben? Gibt es eine Möglichkeit, eine XML-Datei zu "aktualisieren" (d. h. eine <node></node> irgendwo in der Mitte). Wie Sie meiner Frage richtig entnehmen können, bin ich hier ein Neuling.

0 Stimmen

Überschreiben Sie sie einfach und lassen Sie das Frontend nach ihr fragen.

0 Stimmen

Das ist eine schöne Art, es zu tun! Und wenn Sie wirklich die ganze Geschichte der Ausführung des Skripts behalten wollen, fügen Sie einfach weiter Knoten an die XML, eine nette Bibliothek wie lxml wird Ihr Leben so viel einfacher für diese Xml-Erstellung Aufgabe.

0voto

dawg Punkte 89931

Wenn Sie eher eine schnelle Lösung als eine vollständige Webseite benötigen, besuchen Sie SimpleHTTPServer Sie können Ihre Zustandsinformationen in Form einer Datei in ein Verzeichnis schreiben, und sie werden dort aktualisiert, damit andere sie sehen können.

Nicht schön, aber sehr schnell und sehr einfach.

Für eine Demonstration geben Sie einfach ein python -m SimpleHTTPServer Dadurch wird eine Webseite mit der Adresse http://[your computer's name or IP]:8000 mit dem Inhalt des aktuellen Arbeitsverzeichnisses, in dem es sich beim Start befindet. Die Dateien sind direkt miteinander verknüpft. Wenn Sie auf eine Datei klicken, wird sie im Browser angezeigt; wenn Sie auf ein Verzeichnis klicken, wechseln Sie in dieses Verzeichnis und sein Inhalt wird aufgelistet.

Für Ihre Zwecke können Sie mit einem leeren Verzeichnis beginnen und Dateien erstellen, die den Schritten entsprechen, die Sie melden möchten. Sie könnten Dateien mit dem Namen Ihrer Schritte anlegen, z. B. "Schritt 1.txt", und detailliertere Informationen in dieser Datei. Schritt 1 könnte ein Verzeichnis sein, das Ihr Skript erstellt, wenn Schritt 1 abgeschlossen ist, usw.

Alternativ können Sie auch Verdreht die es Ihnen ermöglicht, HTTP-Anfragen direkt aus Ihrem Python-Skript zu bedienen.

Wenn Sie etwas ausgefallener werden wollen, können Sie im Wesentlichen die gleiche Methode anwenden. Von Ihrem Python-Skript aus schreiben Sie die Ausgabe in Dateien in einem leeren Verzeichnis. Schreiben Sie auf einem Webserver mit PHP ein triviales Skript, das dieses Verzeichnis prüft und anzeigt, was gefunden wurde. Setzen Sie das Aktualisierungsintervall der Seite auf einen bestimmten Wert, und die Seite aktualisiert sich in den Browsern der Betrachter von selbst.

0voto

Omar Abid Punkte 15276

Ich habe keine Ahnung, wie Python funktioniert, aber wenn es PHP wäre, wäre es einfach (wenn man weiß, was man tun sollte).

Nehmen wir an, meine Anwendung ist myapp.py und sie arbeitet von Schritt 1 bis Schritt N. Ich möchte, dass sie (einfacher Text) eine Zahl zurückgibt. Diese Zahl ist die Schrittnummer der Anwendung. Wenn ich zum Beispiel aufrufe http://localhost/myapp.py gibt er 5 zurück. Nach 30 Minuten lade ich die Seite neu und es werden 15 angezeigt.

Nun zur JavaScript-Sache. Ich werde die Verwendung von jQuery empfehlen. Es macht die Dinge viel einfacher und schneller. Alles, was ich tun würde, ist

$('#streaming').load('http://localhost/myapp.py');

Dadurch wird der Inhalt der Seite in das DIV mit ID = Streaming geladen. Dies geschieht jedoch nur, wenn Sie die Seite laden. Damit dies alle x Sekunden geschieht, verwenden Sie die JavaScript-Funktion settimeout.

var t=setTimeout("javascript statement",milliseconds);

Es wäre besser, den Teil, der den Schritt lädt, in einer Funktion zu speichern und sie beim Laden der Seite und mit setTimeout aufzurufen. Es wäre auch hilfreich, setTimeout zu stoppen, sobald Ihr Skript nicht mehr funktioniert (mit einer speziellen Zahl/Meldung).

0voto

li.davidm Punkte 10755

Bei der Verwendung von einfachem JavaScript haben Sie die Wahl zwischen Comet, WebSockets und Ajax. Ich weiß allerdings nicht wirklich viel über diese Möglichkeiten. Sehen Sie sich einige dieser Websites an:

http://en.wikipedia.org/wiki/Comet_(Programmierung)

http://www.websockets.org/

Soweit ich weiß, beinhaltet Comet einfach eine langlebige Ajax-Anfrage an den Webserver, wo ein Skript Daten nach Bedarf pushen kann. WebSockets werden nur von den allerneuesten Versionen einiger Browser unterstützt. Die einfachste Lösung wäre das, was Omar Abid vorgeschlagen hat: den Webserver hin und wieder per Ajax abfragen.

0voto

Paul Smith Punkte 454

Sie könnten Ihrer Anwendung eine Serverinstanz hinzufügen, die auf Anfragen an einem bestimmten Port mit dem antwortet, was Ihre Anwendung gemeinsam nutzen möchte. Starten Sie dies in einem separaten Thread mit Zugriff auf die Statusinformationen der Anwendung und lassen Sie Ihre Webseite oder Überwachungsprogramme eine Anfrage an diesen Port senden. Sie können natürlich auf verschiedene Anfragen auf unterschiedliche Weise reagieren. Alle Informationen, die Sie benötigen, sind auf https://pymotw.com/3/socket/tcp.html aber der nachstehende Code wird Ihnen den Einstieg erleichtern:

# borrowed from https://pymotw.com/3/socket/tcp.html
import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the port
# (the host name used will need to be pingable from the requesting service)
server_address = ('', 10000)
print('starting up on {} port {}'.format(*server_address))
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

while True:  # add a terminator based on your application state
    # Wait for a connection
    print('waiting for a connection')
    connection, client_address = sock.accept()
    try:
        print('connection from', client_address)

        # Receive the data in small chunks and retransmit it
        while True:
            data = connection.recv(16)
            # print('received {!r}'.format(data))
            if data:  # add a check to ensure the request is valid
                print('sending data back to the client')
                data = 'Current application state is:' + getStatus()
                connection.sendall(data.encode())
            else:
                print('no data from', client_address)
                break
    finally:
        # Clean up the connection
        connection.close()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X