Usereingabe von Python von HTML übernehmen lassen

einfachpeer

Lt. Commander
Registriert
Apr. 2022
Beiträge
1.319
Hallo Leute,

aktuell sitze ich an einer Art Fernwartungssystem.
Über die python konsole funktioniert alles 1a. Doch ich möchte die jetzt (noch) manuelle Usereingabe über HTML Buttons steuern. D.h wenn ich in HTML einen Button drücke schreibt er z.B eine 1 in die py und schickt es ab.
Es soll auch die Antwort in HTML angezeigt werden. Google und KI liefern mir keine Ergebnisse, mir selber fällt auch keine Lösung ein.
Habt ihr Tipps oder Lösungen ?

Client.py
Code:
import socket
import subprocess
import sys
import time




def read_server_config():
    with open("client_config.txt", "r") as file:
        return file.readline().strip()




def run_client(server_ip, server_port):
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((server_ip, server_port))


    client_id = client_socket.recv(1024).decode()
    print(f"Ihre ID: {client_id}")


    while True:
        command = client_socket.recv(4096).decode()
        if command == 'disconnect':
            break
        elif command == 'restart':
            # Führen Sie hier den Neustart-Code aus
            pass
        else:
            # Führen Sie den Befehl aus und senden Sie das Ergebnis zurück
            output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True)
            client_socket.send(output.encode())


    client_socket.close()


if __name__ == "__main__":
    server_info = read_server_config().split(":")
    SERVER_IP = server_info[0]
    SERVER_PORT = int(server_info[1]) if len(server_info) > 1 else 8080
    while True:
        try:
            run_client(SERVER_IP, SERVER_PORT)
            break  # Beenden Sie die Schleife, wenn die Verbindung erfolgreich war
        except ConnectionRefusedError:
            print("Verbindung zum Server fehlgeschlagen. Versuche es erneut in 5 Sekunden...")
            time.sleep(5)

server
Code:
import socket
import threading
import hashlib
import mysql.connector
import queue
import time


def read_server_ip():
    with open("server_config.txt", "r") as file:
        return file.readline().strip()
        
        
# MySQL-Datenbankverbindung
db_conn = mysql.connector.connect(
    host="localhost",
    user="root",
    password="",
    database="clients_db"
)
db_cursor = db_conn.cursor()

# Erstellen der Tabelle, falls sie nicht existiert
db_cursor.execute("""
CREATE TABLE IF NOT EXISTS clients (
    id INT AUTO_INCREMENT PRIMARY KEY,
    mac_address VARCHAR(255) UNIQUE,
    address VARCHAR(255),
    `key` VARCHAR(255)
)
""")
db_conn.commit()

# Dictionary zur Speicherung von Client-Sockets und deren IDs
active_clients = {}
client_queues = {}

def generate_mac_address(ip_address):
    mac = hashlib.md5(ip_address.encode()).hexdigest()[0:12]
    return ':'.join(mac[i:i+2] for i in range(0, 12, 2))

def create_client_id(ip_address):
    mac_address = generate_mac_address(ip_address)
    db_cursor.execute("SELECT id FROM clients WHERE mac_address = %s", (mac_address,))
    existing_client_id = db_cursor.fetchone()
    if existing_client_id:
        return existing_client_id[0]
    else:
        key = hashlib.sha256(mac_address.encode()).hexdigest()  # Einzigartiger Schlüssel für den Client
        db_cursor.execute("INSERT INTO clients (mac_address, address, `key`) VALUES (%s, %s, %s)", (mac_address, ip_address, key))
        db_conn.commit()
        db_cursor.execute("SELECT id FROM clients WHERE mac_address = %s", (mac_address,))
        new_client_id = db_cursor.fetchone()
        return new_client_id[0]

def handle_client(client, address):
    client_id = create_client_id(address[0])
    active_clients[client_id] = client
    client_queues[client_id] = queue.Queue()

    threading.Thread(target=client_communication, args=(client_id, client_queues[client_id])).start()

    print(f"Client-ID {client_id} wurde zugewiesen zu {address}.")
    client.send(str(client_id).encode())

    while True:
        time.sleep(1)  # Blockiert nicht den Hauptthread

    client.close()
    print(f"Verbindung mit Client {client_id} geschlossen.")

def client_communication(client_id, client_queue):
    client = active_clients[client_id]
    while True:
        command = client_queue.get()
        if command == 'disconnect':
            client.close()
            break
        elif command == 'restart':
            client.send(command.encode())
            break
        else:
            client.send(command.encode())
            output = client.recv(4096).decode()
            print(f"Antwort von Client {client_id}: {output}")

def admin_console():
    while True:
        client_id = input("Geben Sie die ID des Clients ein, mit dem Sie sich verbinden möchten, oder 'list' um alle zu sehen: ")
        if client_id == 'list':
            print("Aktive Clients:")
            for cid in active_clients.keys():
                print(f"Client-ID: {cid}")
        elif client_id.isdigit() and int(client_id) in active_clients:
            client_queue = client_queues[int(client_id)]
            print(f"Verbunden mit Client {client_id}.")
            while True:
                command = input(f"Geben Sie einen Befehl ein, den Sie an Client {client_id} senden möchten ('next_client' um zu wechseln): ")
                if command == 'disconnect':
                    client_queue.put(command)
                    break
                elif command == 'next_client':
                    
                    break
                else:
                    client_queue.put(command)
        else:
            print("Ungültige Client-ID.")

def run_server():
    server_ip = read_server_ip()
    print(f"Server läuft auf {server_ip} und wartet auf Verbindungen...")
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((server_ip, 8080))  # Verwendung der gelesenen IP
    server_socket.listen()

    admin_thread = threading.Thread(target=admin_console)
    admin_thread.start()

    try:
        while True:
            client_socket, address = server_socket.accept()
            threading.Thread(target=handle_client, args=(client_socket, address)).start()
    except KeyboardInterrupt:
        print("Server wird heruntergefahren...")
    finally:
        server_socket.close()

if __name__ == "__main__":
    run_server()
 
Musst Du die Server-Client-Datenbank Kommunikation wirklich von klein auf schreiben? Falls nein, informiere Dich über das Model-View-Konzept und wie es in Frameworks, wie zB Django, umgesetzt worden ist. Damit kannst Du dann eine schöne Python-HTML Verschränkung programmieren. Hoffe dieser Hinweis hilft Dir.
 
  • Gefällt mir
Reaktionen: Bright0001, einfachpeer und Rexaris
Ich muss mich Rexaris anschließen, dass ich das eigentliche Problem nicht verstehe. Ein Backend-Service der HTTP-Requests verarbeitet und Zeug durch die Gegend schickt ist nicht gerade neu, und nicht wirklich ein Problem.

Zumal manuelles Networking alles andere als Spaß macht, und man sich besonders als Anfänger sehr sicher sein kann, dass es schon ein Framework in der eigenen Lieblingssprache gibt, das es besser macht. Lies dich in RESTful-Services ein und was das MVC-Pattern ist, und du hast die Kiste innerhalb von ner Stunde fertig.

Und dass weder Google noch AI helfen konnten, ist auch wild; Wonach genau hast du gefragt?
2023-12-04_23h13_55.png

Keinen Plan ob es läuft, aber als Ausgangspunkt sicherlich mehr als brauchbar.
 
Hab es heute abend mit flask gemacht. Hab die verbindung an sich aufgesetzt aber es passiert nix wenn ich die Buttons drücke. Danke erstmal an alle, aber ich hab genug vorm Rechner gesessen für heute😂 Wenn ihr mögt, stelle ich den Code morgen nochmal rein oder ich versuche es erst selber zu lösen. Gute nacht
Ergänzung ()

Bzw es wird einfach nur die letzte ausgabe wiederholt, aber das ist ein problem für morgen
 
Naja Buttons müssen entweder in einem Form und als submit deklariert sein. Oder per Javascript/Ajax die Requests absenden. Beides easy machbar mit Flask, hab damit auch erst vor 3 oder 4 Wochen angefangen.

Wenn's Dir hilft kannst hier in mein reccht überschaubares Projekt reinschauen: https://github.com/Drexel2k/raspiFM/tree/main/src/webui

In der stationsearch ist beides drin, Form per Submit Button , das die eingegeben Werte auch wieder anzeigt und Ajax Requests....

Allerdings kotzt mich Python als Sprache ziemlich an, aber das ist ein anderes Thema. 😅
 
  • Gefällt mir
Reaktionen: einfachpeer
Guten Morgen zusammen. Weiter gehts mit meinem Projekt. Da die Server.py auf Windows Server ausgeführt wird, dachte ich auch gerade an VBS. Kann ich vielleicht vbs einfacher mit Html verknüpfen und ihn da reinschreiben lassen ? Das problem ist ich will einen Button drücken in HTML und er geht in die Command ine meines Python Programms und schreibt da eine Zahl rein, wie wenn ich es manuell tun würde
 
Warum willst du den Umweg über die Command-Line gehen und das Ereignis vom Button-Klick nicht direkt an eine Python-Funktion übergeben?
 
ja stimmt. Stehe da etwas auf dem schlauch. Hättest du vielleicht ein ganz einfaches beispiel in Verbindung mit meinem Code?
 
sorry, da fehlt mir gerade die Zeit mich in deinen Code reinzufuchsen.
@Bright0001 hat doch ein Minimalbeispiel gepostet. Dort geht auch hervor, welche Funktion auf den Button reagiert. Die musst du einfach nach deinen Wünschen erweitern.
 
Wie verlinke sage ich dem button denn jetyt, dass er einen saty byw befehl da reinschriben soll
 
Nach dem gucken vom YT Kurs von "Programmieren lernen" über Flask klappt es. Danke
 
Zurück
Oben