| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- from fastapi import APIRouter, HTTPException
- from pydantic import BaseModel
- from typing import Optional, Any
- from app.agents.report_parse_agent import ReportParseAgent
- import logging
- import os
- import json
- logger = logging.getLogger(__name__)
- router = APIRouter(prefix="/api/v1", tags=["report_parse"])
- _agent = None
- def get_agent():
- global _agent
- if _agent is None:
- _agent = ReportParseAgent()
- return _agent
- class ParseRequest(BaseModel):
- file_path: str
- family_id: Optional[int] = None
- user_id: Optional[int] = None
- class ParseResponse(BaseModel):
- code: int = 200
- message: str = "ok"
- data: dict = {}
- @router.post("/report/parse", response_model=ParseResponse)
- async def parse_report(req: ParseRequest):
- if not os.path.exists(req.file_path):
- raise HTTPException(status_code=400, detail=f"文件不存在: {req.file_path}")
- logger.info("report_parse: file_path=%s family_id=%s user_id=%s",
- req.file_path, req.family_id, req.user_id)
- agent = get_agent()
- try:
- result = await agent.parse(req.file_path)
- return ParseResponse(data=result)
- except Exception as e:
- logger.error("报告解析失败: %s", e, exc_info=True)
- return ParseResponse(code=500, message=f"解析失败: {str(e)}", data={})
- class GenericParseRequest(BaseModel):
- file_path: str
- extra_context: Optional[dict] = None
- class GenericParseResponse(BaseModel):
- code: int = 200
- message: str = "ok"
- data: dict = {}
- @router.post("/report/parse-generic", response_model=GenericParseResponse)
- async def parse_report_generic(req: GenericParseRequest):
- """通用报告 LLM 兜底解析。
- 适用于指纹检测未匹配的未知类型报告。
- 直接交给 LLM 提取结构化数据,不经过算法预解析。
- """
- if not os.path.exists(req.file_path):
- raise HTTPException(status_code=400, detail=f"文件不存在: {req.file_path}")
- logger.info("report_parse_generic: file_path=%s", req.file_path)
- agent = get_agent()
- try:
- result = await agent.parse_generic(req.file_path, req.extra_context)
- return GenericParseResponse(data=result)
- except Exception as e:
- logger.error("通用报告解析失败: %s", e, exc_info=True)
- return GenericParseResponse(code=500, message=f"解析失败: {str(e)}", data={})
- class TypedParseRequest(BaseModel):
- file_path: str
- report_type: str = "auto"
- extra_context: Optional[dict] = None
- class TypedParseResponse(BaseModel):
- code: int = 200
- message: str = "ok"
- data: dict = {}
- @router.post("/report/parse-typed", response_model=TypedParseResponse)
- async def parse_report_typed(req: TypedParseRequest):
- """按报告类型解析。
- 支持的报告类型:
- - auto: 自动检测(默认)
- - brain_status: 脑状态测量报告
- - cognitive_aptitude: 先天智力潜能/皮纹学测评报告
- - scanned_image: 扫描图片 PDF(无文字层,需多模态 LLM)
- - generic: 通用 LLM 解析
- - gut_flora: 肠道菌群报告(算法解析 + LLM 兜底)
- """
- if not os.path.exists(req.file_path):
- raise HTTPException(status_code=400, detail=f"文件不存在: {req.file_path}")
- logger.info("report_parse_typed: file_path=%s type=%s",
- req.file_path, req.report_type)
- agent = get_agent()
- try:
- result = await agent.parse_by_type(req.file_path, req.report_type, req.extra_context)
- return TypedParseResponse(data=result)
- except Exception as e:
- logger.error("类型报告解析失败: %s", e, exc_info=True)
- return TypedParseResponse(code=500, message=f"解析失败: {str(e)}", data={})
- class TypedParseRequest2(BaseModel):
- file_path: str
- @router.post("/report/detect-type", response_model=TypedParseResponse)
- async def detect_report_type(req: TypedParseRequest2):
- """检测报告类型,返回检测结果(不执行解析)。"""
- if not os.path.exists(req.file_path):
- raise HTTPException(status_code=400, detail=f"文件不存在: {req.file_path}")
- agent = get_agent()
- try:
- detected = agent._detect_report_type(req.file_path)
- return TypedParseResponse(data={"detectedType": detected})
- except Exception as e:
- logger.error("报告类型检测失败: %s", e, exc_info=True)
- return TypedParseResponse(code=500, message=f"检测失败: {str(e)}", data={})
|