智教助手平台:完整初始化
- 前端:Vue3 + TS + Element Plus,24 个页面路由(课件/组题/教案/动画/思维导图/作文批改/命题/课堂/资源/社区等) - 后端:FastAPI + SQLAlchemy + SQLite,17 个路由模块,AI 服务层含降级模板 - AI:glm-5.x 推理模型已禁用思维链,确保输出真实内容 - 修复:ai_service 两处请求体注入 enable_thinking/thinking disabled - 测试账号:13900999999 / test1234
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user