145 lines
4.7 KiB
Python
145 lines
4.7 KiB
Python
from fastapi import FastAPI, UploadFile, File, HTTPException, Form
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import FileResponse
|
|
from typing import List
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
from dotenv import load_dotenv
|
|
|
|
# 加载环境变量
|
|
load_dotenv()
|
|
|
|
from services.ocr_service import OCRService
|
|
from services.llm_service import LLMService
|
|
from services.report_integrator import ReportIntegrator
|
|
from services.pdf_service import PDFService
|
|
from services.template_service import TemplateService
|
|
from services.batch_report_service import BatchReportService
|
|
from services.deepseek_health_service import DeepSeekHealthService
|
|
|
|
app = FastAPI(title="医疗报告分析系统")
|
|
|
|
# CORS配置
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["http://localhost:5173", "http://localhost:3000"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# 初始化服务(仅用于综合报告流程)
|
|
ocr_service = OCRService()
|
|
llm_service = LLMService()
|
|
report_integrator = ReportIntegrator(llm_service)
|
|
pdf_service = PDFService()
|
|
template_service = TemplateService()
|
|
batch_service = BatchReportService(ocr_service, llm_service, pdf_service, template_service)
|
|
|
|
# 检查 DeepSeek 配置状态
|
|
deepseek_key = os.getenv("DEEPSEEK_API_KEY", "")
|
|
if deepseek_key:
|
|
print("✓ DeepSeek API Key 已配置,健康评估和建议功能已启用")
|
|
else:
|
|
print("⚠ DeepSeek API Key 未配置,健康评估和建议功能将被跳过")
|
|
|
|
|
|
@app.get("/")
|
|
async def root():
|
|
return {"message": "医疗报告分析系统API", "status": "running"}
|
|
|
|
|
|
@app.post("/api/comprehensive-report")
|
|
async def generate_comprehensive_report(
|
|
files: List[UploadFile] = File(...),
|
|
patient_name: str = Form(default="患者")
|
|
):
|
|
"""
|
|
批量上传并生成综合健康报告
|
|
注意:上传的文件不会永久存储,处理完后自动删除
|
|
"""
|
|
temp_files = []
|
|
|
|
try:
|
|
# 验证文件类型
|
|
allowed_extensions = {".pdf", ".jpg", ".jpeg", ".png", ".bmp"}
|
|
|
|
# 临时保存上传的文件
|
|
for file in files:
|
|
file_ext = Path(file.filename).suffix.lower()
|
|
|
|
if file_ext not in allowed_extensions:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"不支持的文件格式: {file.filename}"
|
|
)
|
|
|
|
# 创建临时文件
|
|
temp_file = tempfile.NamedTemporaryFile(
|
|
delete=False,
|
|
suffix=file_ext,
|
|
dir=str(batch_service.temp_dir)
|
|
)
|
|
|
|
# 写入文件内容
|
|
content = await file.read()
|
|
temp_file.write(content)
|
|
temp_file.close()
|
|
|
|
temp_files.append(temp_file.name)
|
|
|
|
# 批量处理报告
|
|
result = batch_service.process_multiple_reports(
|
|
file_paths=temp_files,
|
|
patient_name=patient_name
|
|
)
|
|
|
|
return {
|
|
"success": True,
|
|
"patient_name": result["patient_name"],
|
|
"report_count": result["report_count"],
|
|
"pdf_filename": Path(result["pdf_path"]).name,
|
|
"pdf_path": result["pdf_path"],
|
|
"generated_at": result["generated_at"],
|
|
# 包含健康评估和建议内容
|
|
"health_assessment": result.get("analysis", {}).get("health_assessment", {}),
|
|
"health_advice": result.get("analysis", {}).get("health_advice", {})
|
|
}
|
|
|
|
except HTTPException:
|
|
# 清理临时文件
|
|
batch_service._cleanup_temp_files(temp_files)
|
|
raise
|
|
except Exception as e:
|
|
# 清理临时文件
|
|
batch_service._cleanup_temp_files(temp_files)
|
|
import traceback
|
|
error_detail = f"综合报告生成失败: {str(e)}\n{traceback.format_exc()}"
|
|
print(error_detail) # 打印完整错误堆栈
|
|
raise HTTPException(status_code=500, detail=f"综合报告生成失败: {str(e)}")
|
|
|
|
|
|
@app.get("/api/comprehensive-report/download/{pdf_filename}")
|
|
async def download_comprehensive_report(pdf_filename: str):
|
|
"""下载综合健康报告"""
|
|
try:
|
|
pdf_path = pdf_service.output_dir / pdf_filename
|
|
|
|
if not pdf_path.exists():
|
|
raise HTTPException(status_code=404, detail="PDF文件不存在")
|
|
|
|
return FileResponse(
|
|
path=str(pdf_path),
|
|
media_type="application/pdf",
|
|
filename=pdf_filename
|
|
)
|
|
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"下载失败: {str(e)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=8001)
|