init repo
This commit is contained in:
0
app/api/__init__.py
Normal file
0
app/api/__init__.py
Normal file
110
app/api/routes.py
Normal file
110
app/api/routes.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""API routes for report generation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.graph.state import ReportState
|
||||
from app.pipeline.orchestrator import PipelineOrchestrator
|
||||
from app.pipeline.task import create_report_state
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
# In-memory store (swap for DB later)
|
||||
reports: dict[str, ReportState] = {}
|
||||
orchestrator = PipelineOrchestrator()
|
||||
|
||||
|
||||
class CreateReportRequest(BaseModel):
|
||||
requirement: str
|
||||
report_type: str = "行业分析报告"
|
||||
extra_data: str = ""
|
||||
output_formats: list[str] = ["docx"]
|
||||
client_id: str | None = None
|
||||
|
||||
|
||||
class ReportResponse(BaseModel):
|
||||
id: str
|
||||
current_node: str
|
||||
error: str | None = None
|
||||
generated_files: list[str] = []
|
||||
node_history: list[dict] = []
|
||||
revision_count: int = 0
|
||||
|
||||
|
||||
def _to_response(state: ReportState) -> ReportResponse:
|
||||
return ReportResponse(
|
||||
id=state.id,
|
||||
current_node=state.current_node,
|
||||
error=state.error,
|
||||
generated_files=state.generated_files,
|
||||
node_history=state.node_history,
|
||||
revision_count=state.revision_count,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/reports", response_model=ReportResponse)
|
||||
async def create_report(req: CreateReportRequest):
|
||||
"""Create and execute a report generation pipeline."""
|
||||
state = create_report_state(
|
||||
requirement=req.requirement,
|
||||
report_type=req.report_type,
|
||||
extra_data=req.extra_data,
|
||||
output_formats=req.output_formats,
|
||||
client_id=req.client_id,
|
||||
)
|
||||
reports[state.id] = state
|
||||
|
||||
# Run the full graph (blocking for now, add task queue later)
|
||||
state = await orchestrator.run(state)
|
||||
reports[state.id] = state
|
||||
|
||||
if state.error:
|
||||
raise HTTPException(status_code=500, detail=state.error)
|
||||
|
||||
return _to_response(state)
|
||||
|
||||
|
||||
@router.get("/reports/{report_id}", response_model=ReportResponse)
|
||||
async def get_report(report_id: str):
|
||||
"""Get report status and results."""
|
||||
state = reports.get(report_id)
|
||||
if not state:
|
||||
raise HTTPException(status_code=404, detail="Report not found")
|
||||
return _to_response(state)
|
||||
|
||||
|
||||
@router.get("/reports")
|
||||
async def list_reports():
|
||||
"""List all reports."""
|
||||
return [_to_response(s) for s in reports.values()]
|
||||
|
||||
|
||||
@router.get("/reports/{report_id}/detail")
|
||||
async def get_report_detail(report_id: str):
|
||||
"""Get full report detail including draft and research."""
|
||||
state = reports.get(report_id)
|
||||
if not state:
|
||||
raise HTTPException(status_code=404, detail="Report not found")
|
||||
return {
|
||||
"id": state.id,
|
||||
"requirement": state.requirement,
|
||||
"decomposition": state.decomposition,
|
||||
"research_results": [
|
||||
{
|
||||
"description": r.description,
|
||||
"status": r.status.value,
|
||||
"duration_ms": r.duration_ms,
|
||||
}
|
||||
for r in state.research_results
|
||||
],
|
||||
"draft": state.draft,
|
||||
"review": state.review,
|
||||
"generated_files": state.generated_files,
|
||||
"node_history": state.node_history,
|
||||
}
|
||||
Reference in New Issue
Block a user