Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel, Field | |
| import time | |
| import logging | |
| import os | |
| from typing import Optional | |
| from engine import NexusCoreEngine | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| logger = logging.getLogger(__name__) | |
| app = FastAPI(title="Nexus-Core API", version="2.0.0") | |
| app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"]) | |
| engine = None | |
| class MoveRequest(BaseModel): | |
| fen: str | |
| depth: Optional[int] = Field(4, ge=1, le=6) | |
| time_limit: Optional[int] = Field(3000, ge=1000, le=10000) | |
| class MoveResponse(BaseModel): | |
| best_move: str | |
| evaluation: float | |
| depth_searched: int | |
| nodes_evaluated: int | |
| time_taken: int | |
| class HealthResponse(BaseModel): | |
| status: str | |
| model_loaded: bool | |
| version: str | |
| async def startup_event(): | |
| global engine | |
| logger.info("🚀 Starting Nexus-Core...") | |
| # FIXED: Check both possible paths | |
| possible_paths = [ | |
| "/app/app/models/nexus-core.onnx", # When uploaded to app/models/ | |
| "/app/models/nexus-core.onnx" # When uploaded to models/ | |
| ] | |
| model_path = None | |
| for path in possible_paths: | |
| if os.path.exists(path): | |
| model_path = path | |
| logger.info(f"✅ Found model at: {path}") | |
| break | |
| if not model_path: | |
| logger.error("❌ Model not found in any expected location") | |
| logger.error(f"Checked paths: {possible_paths}") | |
| # List all .onnx files | |
| for root, dirs, files in os.walk("/app"): | |
| for file in files: | |
| if file.endswith('.onnx'): | |
| logger.error(f"Found .onnx at: {os.path.join(root, file)}") | |
| raise FileNotFoundError("Model not found") | |
| try: | |
| engine = NexusCoreEngine(model_path=model_path, num_threads=2) | |
| logger.info("✅ Engine loaded!") | |
| except Exception as e: | |
| logger.error(f"❌ Failed: {e}", exc_info=True) | |
| raise | |
| async def health_check(): | |
| return {"status": "healthy" if engine else "unhealthy", "model_loaded": engine is not None, "version": "2.0.0"} | |
| async def get_move(request: MoveRequest): | |
| if not engine: raise HTTPException(503, "Not loaded") | |
| if not engine.validate_fen(request.fen): raise HTTPException(400, "Invalid FEN") | |
| start = time.time() | |
| try: | |
| result = engine.get_best_move(request.fen, request.depth, request.time_limit) | |
| logger.info(f"✓ {result['best_move']} | {result['evaluation']:+.2f} | {result['time_taken']}ms") | |
| return MoveResponse(**result) | |
| except Exception as e: | |
| logger.error(f"Error: {e}", exc_info=True) | |
| raise HTTPException(500, str(e)) | |
| async def root(): | |
| return {"name": "Nexus-Core", "version": "2.0.0", "status": "online" if engine else "starting"} | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860, log_level="info") |