Spaces:
Sleeping
Sleeping
| """Application factory for the Flask service.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from time import perf_counter | |
| from flask import Flask, Response, g, jsonify, request | |
| from flask_cors import CORS | |
| from werkzeug.exceptions import HTTPException | |
| from api_layer.routes import build_routes | |
| from brain.decision_maker import DecisionEngine | |
| from config.settings import AppSettings, configure_logging, load_settings | |
| from core_engine.analytics import AnalyticsTracker | |
| from core_engine.leaderboard import LeaderboardStore | |
| from core_engine.simulator import SimulationEngine | |
| from utils.logger import get_logger | |
| LOGGER = get_logger(__name__) | |
| def create_server(settings: AppSettings | None = None) -> Flask: | |
| """Create and configure the Flask application.""" | |
| app_settings = settings or load_settings() | |
| configure_logging(app_settings) | |
| frontend_dir = Path(__file__).resolve().parent.parent / "frontend" | |
| app = Flask( | |
| __name__, | |
| static_folder=str(frontend_dir), | |
| static_url_path="", | |
| ) | |
| CORS(app, resources={r"/*": {"origins": app_settings.cors_origins}}) | |
| engine = SimulationEngine( | |
| batch_size=app_settings.default_mail_count, | |
| random_seed=app_settings.random_seed, | |
| simulation_mode=app_settings.simulation_mode, | |
| ) | |
| decision_engine = DecisionEngine( | |
| model_type=app_settings.model_type, | |
| hf_model=app_settings.hf_model, | |
| hf_token=app_settings.hf_token, | |
| hf_timeout=app_settings.hf_timeout, | |
| ) | |
| analytics = AnalyticsTracker() | |
| leaderboard = LeaderboardStore() | |
| def log_request_start() -> None: | |
| g.request_started_at = perf_counter() | |
| def log_request_end(response: Response) -> Response: | |
| started_at = getattr(g, "request_started_at", perf_counter()) | |
| elapsed_ms = (perf_counter() - started_at) * 1000 | |
| LOGGER.info( | |
| "%s %s -> %s %.2fms", | |
| request.method, | |
| request.path, | |
| response.status_code, | |
| elapsed_ms, | |
| ) | |
| return response | |
| def dashboard() -> object: | |
| try: | |
| return app.send_static_file("index.html") | |
| except Exception: | |
| LOGGER.exception("Failed to serve dashboard.") | |
| return jsonify({"success": False, "error": "Unable to serve dashboard."}), 500 | |
| def handle_http_error(error: HTTPException) -> tuple[Response, int]: | |
| return ( | |
| jsonify( | |
| { | |
| "success": False, | |
| "error": error.description or "HTTP request failed.", | |
| } | |
| ), | |
| error.code or 500, | |
| ) | |
| def handle_unexpected_error(error: Exception) -> tuple[Response, int]: | |
| LOGGER.exception("Unhandled application error: %s", error) | |
| return jsonify({"success": False, "error": "Internal server error."}), 500 | |
| app.register_blueprint( | |
| build_routes( | |
| engine, | |
| decision_engine=decision_engine, | |
| analytics=analytics, | |
| leaderboard=leaderboard, | |
| max_email_count=app_settings.max_emails, | |
| ) | |
| ) | |
| app.config["simulation_engine"] = engine | |
| app.config["decision_engine"] = decision_engine | |
| app.config["analytics"] = analytics | |
| app.config["leaderboard"] = leaderboard | |
| return app | |