content.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. """内容相关 API 路由。"""
  2. import logging
  3. from fastapi import APIRouter, HTTPException
  4. from ..models.schemas import ChapterContentRequest
  5. from ..services.content_service import ContentService
  6. from ..utils.errors import AppError
  7. from ..utils.sse import sse_chunk, sse_done, sse_error, sse_response
  8. logger = logging.getLogger(__name__)
  9. router = APIRouter(prefix="/api/content", tags=["内容管理"])
  10. @router.post("/generate-chapter")
  11. async def generate_chapter_content(request: ChapterContentRequest):
  12. """为单个章节生成完整内容。"""
  13. try:
  14. content_service = ContentService()
  15. content = await content_service.generate_chapter_content(
  16. chapter=request.chapter,
  17. parent_chapters=request.parent_chapters,
  18. sibling_chapters=request.sibling_chapters,
  19. project_overview=request.project_overview,
  20. )
  21. return {"success": True, "content": content}
  22. except AppError as exc:
  23. raise HTTPException(status_code=exc.status_code, detail=exc.message) from exc
  24. except Exception as exc:
  25. logger.exception("章节内容生成失败")
  26. raise HTTPException(status_code=500, detail=f"章节内容生成失败: {exc}") from exc
  27. @router.post("/generate-chapter-stream")
  28. async def generate_chapter_content_stream(request: ChapterContentRequest):
  29. """流式生成单章节内容。"""
  30. try:
  31. content_service = ContentService()
  32. except AppError as exc:
  33. raise HTTPException(status_code=exc.status_code, detail=exc.message) from exc
  34. async def generate():
  35. try:
  36. async for chunk in content_service.stream_chapter_content(
  37. chapter=request.chapter,
  38. parent_chapters=request.parent_chapters,
  39. sibling_chapters=request.sibling_chapters,
  40. project_overview=request.project_overview,
  41. ):
  42. yield sse_chunk(chunk)
  43. except AppError as exc:
  44. yield sse_error(exc.message)
  45. except Exception:
  46. logger.exception("章节内容流式生成失败")
  47. yield sse_error("章节内容生成失败,请稍后重试")
  48. finally:
  49. yield sse_done()
  50. return sse_response(generate())