from __future__ import annotations import os from pathlib import Path from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from .llm import LLMError, LLMNotConfigured, LLMService, LLMTimeout from .planner import RecommendationService from .schemas import ( HealthResponse, PlanRecommendationRequest, RecommendationResponse, ) try: from dotenv import load_dotenv load_dotenv(Path(__file__).resolve().parent.parent / ".env") except ImportError: # Mock mode can run without python-dotenv during minimal diagnostics. pass llm = LLMService() recommendation_service = RecommendationService(llm) app = FastAPI( title="光明区文旅 POI 推荐 API", version="0.2.0", description="POC:模型仅推荐客户端白名单 POI;路线和时间由客户端确定性计算。", ) origins = [ origin.strip() for origin in os.getenv( "CORS_ORIGINS", "http://localhost:5173,http://127.0.0.1:5173" ).split(",") if origin.strip() ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=False, allow_methods=["GET", "POST"], allow_headers=["content-type"], ) @app.get("/api/v1/health", response_model=HealthResponse) async def health() -> HealthResponse: return HealthResponse( status="ok" if llm.ready else "degraded", mode=llm.mode, configured=llm.configured, ready=llm.ready, ) @app.post("/api/v1/plans", response_model=RecommendationResponse) async def create_plan( request: PlanRecommendationRequest, ) -> RecommendationResponse: try: return await recommendation_service.create(request) except LLMNotConfigured as exc: raise HTTPException(status_code=503, detail=str(exc)) from exc except LLMTimeout as exc: raise HTTPException(status_code=504, detail=str(exc)) from exc except LLMError as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc