Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,33 +2,42 @@
|
|
| 2 |
|
| 3 |
from fastapi import FastAPI, File, UploadFile, HTTPException
|
| 4 |
from fastapi.responses import JSONResponse
|
| 5 |
-
from
|
| 6 |
import logging
|
| 7 |
|
|
|
|
|
|
|
|
|
|
| 8 |
# 设置日志
|
| 9 |
logging.basicConfig(level=logging.INFO)
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
| 12 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
app = FastAPI(
|
|
|
|
| 14 |
title="课堂评价系统 API",
|
| 15 |
description="接收学生发言文本,通过AI模型进行分析并返回评价等级和总结。",
|
| 16 |
-
version="1.
|
| 17 |
)
|
| 18 |
|
| 19 |
-
# --- 关键:实现单例模式 ---
|
| 20 |
-
# 在应用启动时加载一次模型,后续所有请求都复用这个实例
|
| 21 |
-
# 这样可以避免每次请求都重新加载183MB的ONNX模型,极大提高响应速度
|
| 22 |
-
predictor_instance = None
|
| 23 |
-
|
| 24 |
-
@app.on_event("startup")
|
| 25 |
-
def startup_event():
|
| 26 |
-
"""在应用启动时执行,加载模型。"""
|
| 27 |
-
global predictor_instance
|
| 28 |
-
logger.info("应用启动,开始加载模型...")
|
| 29 |
-
predictor_instance = Predictor()
|
| 30 |
-
logger.info("模型加载完成。")
|
| 31 |
-
|
| 32 |
# --- API 端点定义 ---
|
| 33 |
@app.post("/evaluate/",
|
| 34 |
summary="评价文本文件",
|
|
@@ -37,12 +46,14 @@ async def evaluate_text_file(file: UploadFile = File(...)):
|
|
| 37 |
"""
|
| 38 |
接收安卓App上传的文本文件,进行评价。
|
| 39 |
"""
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
| 41 |
if file.content_type != "text/plain":
|
| 42 |
raise HTTPException(status_code=400, detail="文件格式错误,请上传 .txt 文件。")
|
| 43 |
|
| 44 |
try:
|
| 45 |
-
# 读取文件内容
|
| 46 |
contents = await file.read()
|
| 47 |
text = contents.decode('utf-8')
|
| 48 |
|
|
@@ -52,14 +63,10 @@ async def evaluate_text_file(file: UploadFile = File(...)):
|
|
| 52 |
logger.info(f"接收到文件: {file.filename}, 开始处理...")
|
| 53 |
|
| 54 |
# 使用已加载的模型实例进行预测
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
else:
|
| 60 |
-
# 这种情况理论上不应该发生,因为有startup事件
|
| 61 |
-
logger.error("模型实例未加载!")
|
| 62 |
-
raise HTTPException(status_code=500, detail="服务器内部错误:模型未成功加载。")
|
| 63 |
|
| 64 |
except Exception as e:
|
| 65 |
logger.error(f"处理文件时发生错误: {e}", exc_info=True)
|
|
@@ -68,5 +75,6 @@ async def evaluate_text_file(file: UploadFile = File(...)):
|
|
| 68 |
@app.get("/", summary="服务健康检查")
|
| 69 |
def read_root():
|
| 70 |
"""一个简单的端点,用于检查服务是否正在运行。"""
|
| 71 |
-
return {"status": "ok", "message": "欢迎使用课堂评价系统 API"}
|
|
|
|
| 72 |
|
|
|
|
| 2 |
|
| 3 |
from fastapi import FastAPI, File, UploadFile, HTTPException
|
| 4 |
from fastapi.responses import JSONResponse
|
| 5 |
+
from contextlib import asynccontextmanager
|
| 6 |
import logging
|
| 7 |
|
| 8 |
+
# --- 关键修改:将 Predictor 的导入放在最前面 ---
|
| 9 |
+
from predictor import Predictor
|
| 10 |
+
|
| 11 |
# 设置日志
|
| 12 |
logging.basicConfig(level=logging.INFO)
|
| 13 |
logger = logging.getLogger(__name__)
|
| 14 |
|
| 15 |
+
# --- 关键修改:使用 lifespan 管理模型加载 ---
|
| 16 |
+
# 创建一个全局变量来存放模型实例
|
| 17 |
+
model_instance = {}
|
| 18 |
+
|
| 19 |
+
@asynccontextmanager
|
| 20 |
+
async def lifespan(app: FastAPI):
|
| 21 |
+
# 在应用启动时执行的代码
|
| 22 |
+
logger.info("应用启动,开始加载模型...")
|
| 23 |
+
# 将模型实例存入一个字典中,更灵活
|
| 24 |
+
model_instance["predictor"] = Predictor()
|
| 25 |
+
logger.info("模型加载完成。应用准备就绪。")
|
| 26 |
+
|
| 27 |
+
yield # lifespan的核心,yield之前的代码在启动时运行,之后的在关闭时运行
|
| 28 |
+
|
| 29 |
+
# 在应用关闭时执行的代码(可选)
|
| 30 |
+
model_instance.clear()
|
| 31 |
+
logger.info("应用关闭,模型已卸载。")
|
| 32 |
+
|
| 33 |
+
# 初始化FastAPI应用,并传入lifespan管理器
|
| 34 |
app = FastAPI(
|
| 35 |
+
lifespan=lifespan,
|
| 36 |
title="课堂评价系统 API",
|
| 37 |
description="接收学生发言文本,通过AI模型进行分析并返回评价等级和总结。",
|
| 38 |
+
version="1.1.0" # 版本升级
|
| 39 |
)
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
# --- API 端点定义 ---
|
| 42 |
@app.post("/evaluate/",
|
| 43 |
summary="评价文本文件",
|
|
|
|
| 46 |
"""
|
| 47 |
接收安卓App上传的文本文件,进行评价。
|
| 48 |
"""
|
| 49 |
+
if "predictor" not in model_instance:
|
| 50 |
+
logger.error("模型实例未在lifespan中成功加载!")
|
| 51 |
+
raise HTTPException(status_code=503, detail="服务暂时不可用:模型正在加载或加载失败。")
|
| 52 |
+
|
| 53 |
if file.content_type != "text/plain":
|
| 54 |
raise HTTPException(status_code=400, detail="文件格式错误,请上传 .txt 文件。")
|
| 55 |
|
| 56 |
try:
|
|
|
|
| 57 |
contents = await file.read()
|
| 58 |
text = contents.decode('utf-8')
|
| 59 |
|
|
|
|
| 63 |
logger.info(f"接收到文件: {file.filename}, 开始处理...")
|
| 64 |
|
| 65 |
# 使用已加载的模型实例进行预测
|
| 66 |
+
predictor = model_instance["predictor"]
|
| 67 |
+
result = predictor.predict(text)
|
| 68 |
+
logger.info(f"处理完成,返回结果: {result}")
|
| 69 |
+
return JSONResponse(content=result)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
except Exception as e:
|
| 72 |
logger.error(f"处理文件时发生错误: {e}", exc_info=True)
|
|
|
|
| 75 |
@app.get("/", summary="服务健康检查")
|
| 76 |
def read_root():
|
| 77 |
"""一个简单的端点,用于检查服务是否正在运行。"""
|
| 78 |
+
return {"status": "ok", "message": "欢迎使用课堂评价系统 API v1.1.0"}
|
| 79 |
+
|
| 80 |
|