Files
jiaoyu/backend/main.py
T
Zhang Jing Xuan 0841b1a103 智教助手平台:完整初始化
- 前端:Vue3 + TS + Element Plus,24 个页面路由(课件/组题/教案/动画/思维导图/作文批改/命题/课堂/资源/社区等)
- 后端:FastAPI + SQLAlchemy + SQLite,17 个路由模块,AI 服务层含降级模板
- AI:glm-5.x 推理模型已禁用思维链,确保输出真实内容
- 修复:ai_service 两处请求体注入 enable_thinking/thinking disabled
- 测试账号:13900999999 / test1234
2026-07-29 16:29:10 +08:00

92 lines
2.8 KiB
Python

import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request as StarletteRequest
from starlette.responses import JSONResponse
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from services.limiter import limiter
from fastapi.staticfiles import StaticFiles
from config import get_settings
from database import engine, Base
import models # noqa: F401
from routers import auth, courseware, animation, exercise, lesson_plan, essay, ai, resource, community, exam, classroom, material, search, admin, mindmap, notification, chat
settings = get_settings()
@asynccontextmanager
async def lifespan(app: FastAPI):
Base.metadata.create_all(bind=engine)
os.makedirs(settings.UPLOAD_DIR, exist_ok=True)
yield
app = FastAPI(
title=settings.APP_NAME,
version=settings.APP_VERSION,
lifespan=lifespan,
)
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class BodySizeLimitMiddleware(BaseHTTPMiddleware):
"""Reject request bodies exceeding MAX_REQUEST_BODY_SIZE (default 60MB)."""
async def dispatch(self, request: StarletteRequest, call_next):
max_size = getattr(settings, "MAX_REQUEST_BODY_SIZE", 60 * 1024 * 1024)
cl = request.headers.get("content-length")
if cl and int(cl) > max_size:
return JSONResponse(
status_code=413,
content={"detail": f"请求体过大,最大允许 {max_size // (1024*1024)}MB"},
)
return await call_next(request)
app.add_middleware(BodySizeLimitMiddleware)
app.include_router(auth.router)
app.include_router(courseware.router)
app.include_router(animation.router)
app.include_router(exercise.router)
app.include_router(lesson_plan.router)
app.include_router(essay.router)
app.include_router(exam.router)
app.include_router(ai.router)
app.include_router(resource.router)
app.include_router(material.router)
app.include_router(community.router)
app.include_router(classroom.router)
app.include_router(search.router)
app.include_router(admin.router)
app.include_router(mindmap.router)
app.include_router(notification.router)
app.include_router(chat.router)
if os.path.exists(settings.UPLOAD_DIR):
app.mount("/uploads", StaticFiles(directory=settings.UPLOAD_DIR), name="uploads")
@app.get("/api/health")
def health_check():
return {"status": "ok", "version": settings.APP_VERSION}
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=settings.DEBUG)