import logging from contextlib import asynccontextmanager from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from app.config import settings from app.mqtt.client import MqttService from app.mqtt.init_dispatcher import InitTaskDispatcher from app.routes import courses, devices, dialogue, scene from app.services.auto_init import AutoInitService from app.services.course_service import CourseService from app.services.device_store import DeviceStore from app.services.init_registry import InitRegistry logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s") logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): device_store = DeviceStore() init_registry = InitRegistry() course_service = CourseService() mqtt_service = MqttService(device_store) init_dispatcher = InitTaskDispatcher(mqtt_service, course_service) auto_init = AutoInitService(init_registry, init_dispatcher, mqtt_service) mqtt_service.auto_init = auto_init app.state.device_store = device_store app.state.init_registry = init_registry app.state.mqtt = mqtt_service app.state.init_dispatcher = init_dispatcher app.state.auto_init = auto_init mqtt_service.start() logger.info("SmartLearning server started") yield mqtt_service.stop() logger.info("SmartLearning server stopped") app = FastAPI( title="SmartLearning Server", description="情境感知智能英语学习系统 - 服务端", version="1.0.0", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(scene.router) app.include_router(dialogue.router) app.include_router(courses.router) app.include_router(devices.router) data_path = Path(settings.data_dir) if data_path.exists(): app.mount("/static", StaticFiles(directory=str(data_path)), name="static") @app.get("/health") async def health(): mqtt = app.state.mqtt if hasattr(app.state, "mqtt") else None return { "status": "ok", "mqtt_connected": mqtt.connected if mqtt else False, }