Spaces:
Sleeping
Sleeping
| import subprocess | |
| import sys | |
| import os | |
| import json | |
| from datetime import datetime | |
| # -------------------------------------------------- | |
| # 🔧 Auto-install Flask if missing | |
| # -------------------------------------------------- | |
| def install_if_missing(package): | |
| try: | |
| __import__(package) | |
| except ImportError: | |
| print(f"⚡ Installing missing package: {package}") | |
| subprocess.check_call([sys.executable, "-m", "pip", "install", package]) | |
| install_if_missing("flask") | |
| # -------------------------------------------------- | |
| # 📦 Imports | |
| # -------------------------------------------------- | |
| from flask import Flask, render_template, request, jsonify, send_from_directory | |
| # -------------------------------------------------- | |
| # ⚙️ CONFIGURATION GLOBALE | |
| # -------------------------------------------------- | |
| PORT = int(os.environ.get("PORT", 7860)) | |
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| CROSS_READING_DIR = os.path.join(BASE_DIR, "cross_reading") | |
| TEMPLATES_DIR = os.path.join(BASE_DIR, "templates") | |
| STATIC_DIR = os.path.join(BASE_DIR, "static") | |
| DATA_DIR = os.path.join(BASE_DIR, "data") | |
| SCENARIOS_FILE = os.path.join(CROSS_READING_DIR, "scenarios.json") | |
| SCENARIOS_LIST_FILE = os.path.join(CROSS_READING_DIR, "scenarios_list.json") | |
| STATS_FILE = os.path.join(CROSS_READING_DIR, "trust_stats.json") | |
| REVIEW_FILE = os.path.join(CROSS_READING_DIR, "review.json") | |
| CALIBRATION_FILE = os.path.join(CROSS_READING_DIR, "calibration-trust.json") | |
| CROSS_HTML = "cross_readers.html" | |
| CROSS_JS = "cross_readers.js" | |
| app = Flask( | |
| __name__, | |
| template_folder=TEMPLATES_DIR, | |
| static_folder=STATIC_DIR | |
| ) | |
| # -------------------------------------------------- | |
| # 🌐 ROUTES UI | |
| # -------------------------------------------------- | |
| def index(): | |
| return render_template("index.html") | |
| def cross_readers(): | |
| if os.path.exists(os.path.join(CROSS_READING_DIR, CROSS_HTML)): | |
| return send_from_directory(CROSS_READING_DIR, CROSS_HTML) | |
| return "cross_readers.html introuvable", 404 | |
| def cross_readers_js(): | |
| return send_from_directory(CROSS_READING_DIR, CROSS_JS) | |
| # -------------------------------------------------- | |
| # 📘 API – SCÉNARIOS | |
| # -------------------------------------------------- | |
| def get_scenarios(): | |
| with open(SCENARIOS_FILE, "r", encoding="utf-8") as f: | |
| return jsonify(json.load(f)) | |
| def get_scenarios_list(): | |
| with open(SCENARIOS_LIST_FILE, "r", encoding="utf-8") as f: | |
| return jsonify(json.load(f)) | |
| # -------------------------------------------------- | |
| # 🔧 API – TRUST CALIBRATION | |
| # -------------------------------------------------- | |
| def get_trust_calibration(): | |
| with open(CALIBRATION_FILE, "r", encoding="utf-8") as f: | |
| return jsonify(json.load(f)) | |
| def save_trust_calibration(): | |
| data = request.json | |
| with open(CALIBRATION_FILE, "w", encoding="utf-8") as f: | |
| json.dump(data, f, indent=2, ensure_ascii=False) | |
| return jsonify({"status": "ok"}) | |
| # -------------------------------------------------- | |
| # 💾 API – TRUST (quantitatif) | |
| # -------------------------------------------------- | |
| def save_trust(): | |
| data = request.json | |
| record = { | |
| "scenario_id": data.get("scenario_id"), | |
| "trust_metrics": data.get("trust_metrics", {}), | |
| "trust_score": data.get("trust_score"), | |
| "comment": data.get("comment"), | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| with open(STATS_FILE, "r+", encoding="utf-8") as f: | |
| content = json.load(f) | |
| content["evaluations"].append(record) | |
| f.seek(0) | |
| json.dump(content, f, indent=2, ensure_ascii=False) | |
| return jsonify({"status": "ok"}) | |
| def get_evaluations(): | |
| with open(STATS_FILE, "r", encoding="utf-8") as f: | |
| data = json.load(f) | |
| # Normalisation métriques | |
| mapping = { | |
| "RA": "AR", | |
| "EA": "AE", | |
| "RE": "ESR", | |
| "MCS": "SDM", | |
| "MS": "SM" | |
| } | |
| for e in data.get("evaluations", []): | |
| if "trust_metrics" in e: | |
| e["trust_metrics"] = { | |
| mapping.get(k, k): v for k, v in e["trust_metrics"].items() | |
| } | |
| return jsonify(data) | |
| # -------------------------------------------------- | |
| # 📝 API – REVIEWS (qualitatif) | |
| # -------------------------------------------------- | |
| def get_reviews(): | |
| with open(REVIEW_FILE, "r", encoding="utf-8") as f: | |
| return jsonify(json.load(f)) | |
| def save_review(): | |
| data = request.json | |
| review = { | |
| "scenario_id": data.get("scenario_id"), | |
| "reader": data.get("reader"), | |
| "review": data.get("review"), | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| with open(REVIEW_FILE, "r+", encoding="utf-8") as f: | |
| content = json.load(f) | |
| content["reviews"].append(review) | |
| f.seek(0) | |
| json.dump(content, f, indent=2, ensure_ascii=False) | |
| return jsonify({"status": "ok"}) | |
| # -------------------------------------------------- | |
| # 📂 ROUTES FICHIERS STATIQUES | |
| # -------------------------------------------------- | |
| def serve_cross_reading(filename): | |
| return send_from_directory(CROSS_READING_DIR, filename) | |
| # -------------------------------------------------- | |
| # 🚀 MAIN | |
| # -------------------------------------------------- | |
| if __name__ == "__main__": | |
| print(f"🚀 Application : http://0.0.0.0:{PORT}") | |
| print(f"📈 Cross Reading : http://0.0.0.0:{PORT}/cross_readers.html") | |
| # Création dossiers | |
| for folder in [CROSS_READING_DIR, TEMPLATES_DIR, STATIC_DIR, DATA_DIR]: | |
| os.makedirs(folder, exist_ok=True) | |
| # Initialisation fichiers | |
| defaults = { | |
| SCENARIOS_FILE: {"scenarios": []}, | |
| SCENARIOS_LIST_FILE: {"scenarios": []}, | |
| STATS_FILE: {"evaluations": []}, | |
| REVIEW_FILE: {"reviews": []}, | |
| CALIBRATION_FILE: { | |
| "metrics": { | |
| "AR": {"min": 0, "max": 5, "weight": 1}, | |
| "AE": {"min": 0, "max": 5, "weight": 1}, | |
| "ESR": {"min": 0, "max": 5, "weight": 1}, | |
| "SDM": {"min": 0, "max": 5, "weight": 1}, | |
| "SM": {"min": 0, "max": 5, "weight": 1} | |
| } | |
| } | |
| } | |
| for path, content in defaults.items(): | |
| if not os.path.exists(path): | |
| with open(path, "w", encoding="utf-8") as f: | |
| json.dump(content, f, indent=2, ensure_ascii=False) | |
| print(f"📄 Créé : {path}") | |
| app.run( | |
| host="0.0.0.0", | |
| port=PORT, | |
| debug=True, | |
| use_reloader=False | |
| ) | |