app.py aktualisiert

This commit is contained in:
2025-08-18 07:20:29 +00:00
parent c111136f57
commit fd80c5ad27

111
app.py
View File

@@ -1,88 +1,59 @@
# app.py # app.py (Version mit pyngrok)
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
import subprocess import subprocess
import sys import sys
import os import os
import logging import logging
from pyngrok import ngrok, conf
from config import Config
# --- Konfiguration ---
# Logging einrichten, um Anfragen und Fehler im Terminal zu sehen
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# --- Flask App Initialisierung ---
app = Flask(__name__) app = Flask(__name__)
# --- SCRIPT MAP --- # SCRIPT MAP bleibt unverändert
# Dies ist die zentrale "Telefonzentrale".
# Hier definieren wir, welcher 'action'-Befehl vom Google Sheet
# welches lokale Skript mit welchen Argumenten startet.
SCRIPT_MAP = { SCRIPT_MAP = {
"run_duplicate_check": { "run_duplicate_check": {"script": "duplicate_checker.py", "args": []},
"script": "duplicate_checker.py", "run_reclassify_branches": {"script": "brancheneinstufung2.py", "args": ["--mode", "reclassify_branches"]},
"args": [] "run_predict_technicians": {"script": "brancheneinstufung2.py", "args": ["--mode", "predict_technicians"]},
},
"run_reclassify_branches": {
"script": "brancheneinstufung.py", # Passen Sie ggf. auf 'brancheneinstufung2.py' an
"args": ["--mode", "reclassify_branches"]
},
"run_predict_technicians": {
"script": "brancheneinstufung.py", # Passen Sie ggf. auf 'brancheneinstufung2.py' an
"args": ["--mode", "predict_technicians"]
},
"run_full_enrichment": {
"script": "brancheneinstufung.py", # Passen Sie ggf. auf 'brancheneinstufung2.py' an
"args": ["--mode", "full_run"]
}
# Hier können in Zukunft einfach weitere Aktionen hinzugefügt werden,
# z.B. für die Generierung von Marketing-Texten.
} }
def setup_ngrok():
"""Konfiguriert und startet den ngrok-Tunnel."""
try:
authtoken = os.environ.get("NGROK_AUTHTOKEN")
if not authtoken:
if os.path.exists("ngrok_authtoken.txt"):
with open("ngrok_authtoken.txt", "r") as f: authtoken = f.read().strip()
if not authtoken:
logging.error("NGROK_AUTHTOKEN nicht gefunden. Tunnel kann nicht gestartet werden.")
return None
conf.get_default().auth_token = authtoken
# Starte den Tunnel zum Port, auf dem Flask laufen wird (8080)
public_url = ngrok.connect(8080, "http")
logging.info(f"!!! Ngrok-Tunnel gestartet: {public_url} !!!")
logging.info("!!! Bitte diese URL im Google Apps Script eintragen (falls sie sich geändert hat). !!!")
return public_url
except Exception as e:
logging.error(f"Fehler beim Starten von ngrok: {e}")
# Beende das Programm, wenn ngrok nicht starten kann
sys.exit(1)
@app.route('/run-script', methods=['POST']) @app.route('/run-script', methods=['POST'])
def run_script(): def run_script():
""" # ... (Ihre run_script Logik bleibt unverändert) ...
Ein universeller Endpunkt, der verschiedene Skripte basierend data = request.get_json()
auf einer 'action'-ID im Request starten kann. action = data.get('action')
""" if not action or action not in SCRIPT_MAP:
try: return jsonify({"status": "error", "message": "Ungültige Aktion."}), 400
data = request.get_json() script_config = SCRIPT_MAP[action]
if not data: command = [sys.executable, script_config["script"]] + script_config["args"]
raise ValueError("Keine JSON-Daten im Request gefunden.") subprocess.Popen(command)
return jsonify({"status": "success", "message": f"Aktion '{action}' gestartet."}), 200
action = data.get('action')
if not action or action not in SCRIPT_MAP:
logging.warning(f"Ungültige oder fehlende Aktion empfangen: {action}")
return jsonify({"status": "error", "message": "Ungültige oder fehlende Aktion."}), 400
script_config = SCRIPT_MAP[action]
script_name = script_config["script"]
script_args = script_config["args"]
# Sicherheitsprüfung: Existiert das Skript?
if not os.path.exists(script_name):
logging.error(f"Skript '{script_name}' für Aktion '{action}' nicht gefunden.")
return jsonify({"status": "error", "message": f"Server-Fehler: Skript '{script_name}' nicht gefunden."}), 500
logging.info(f"Aktion '{action}' empfangen. Starte Skript: '{script_name}' mit Argumenten: {script_args}")
# Stellt sicher, dass der gleiche Python-Interpreter verwendet wird
python_executable = sys.executable
command = [python_executable, script_name] + script_args
# Popen startet den Prozess im Hintergrund und kehrt sofort zurück.
# Das verhindert, dass Google Sheets auf das Ende des Skripts wartet und einen Timeout bekommt.
subprocess.Popen(command)
return jsonify({"status": "success", "message": f"Aktion '{action}' wurde erfolgreich auf dem Server gestartet."}), 200
except Exception as e:
logging.error(f"Ein Fehler ist in der run_script-Route aufgetreten: {e}")
return jsonify({"status": "error", "message": f"Server-Fehler: {str(e)}"}), 500
if __name__ == '__main__': if __name__ == '__main__':
# Startet den Server, erreichbar im lokalen Netzwerk auf Port 8080 # Starte zuerst ngrok
# um Konflikte mit Synology DSM zu vermeiden. setup_ngrok()
# Starte dann den Flask-Server
app.run(host='0.0.0.0', port=8080) app.run(host='0.0.0.0', port=8080)