routes.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from core_domain import ServiceHealth
  2. from fastapi import APIRouter, Depends, HTTPException, Query
  3. from sqlalchemy import text
  4. from sqlalchemy.orm import Session
  5. from app.application.document_parsers import DocumentParseError
  6. from app.application.services import KnowledgeApplicationService
  7. from app.bootstrap.settings import KnowledgeServiceSettings
  8. from app.db.session import get_db
  9. from app.domain.repositories import (
  10. KnowledgeBaseRepository,
  11. KnowledgeChunkRepository,
  12. KnowledgeDocumentRepository,
  13. )
  14. from app.schemas.knowledge import (
  15. KnowledgeBaseCreateRequest,
  16. KnowledgeBaseResponse,
  17. KnowledgeBaseStatusUpdateRequest,
  18. KnowledgeChunkResponse,
  19. KnowledgeDocumentCreateRequest,
  20. KnowledgeDocumentIngestResponse,
  21. KnowledgeDocumentParseRequest,
  22. KnowledgeDocumentParseResponse,
  23. KnowledgeDocumentResponse,
  24. KnowledgeSearchRequest,
  25. KnowledgeSearchResultResponse,
  26. )
  27. router = APIRouter()
  28. def get_knowledge_settings() -> KnowledgeServiceSettings:
  29. return KnowledgeServiceSettings()
  30. def get_knowledge_application_service(
  31. db: Session = Depends(get_db),
  32. settings: KnowledgeServiceSettings = Depends(get_knowledge_settings)) -> KnowledgeApplicationService:
  33. return KnowledgeApplicationService(
  34. settings=settings,
  35. base_repository=KnowledgeBaseRepository(db),
  36. document_repository=KnowledgeDocumentRepository(db),
  37. chunk_repository=KnowledgeChunkRepository(db))
  38. @router.get("/health", response_model=ServiceHealth)
  39. def health_check(db: Session = Depends(get_db)) -> ServiceHealth:
  40. db.execute(text("SELECT 1"))
  41. return ServiceHealth(service="knowledge-service", status="ok", database="ok")
  42. @router.post("/bases", response_model=KnowledgeBaseResponse)
  43. def create_base(
  44. payload: KnowledgeBaseCreateRequest,
  45. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> KnowledgeBaseResponse:
  46. return KnowledgeBaseResponse.from_entity(service.create_base(payload))
  47. @router.get("/bases", response_model=list[KnowledgeBaseResponse])
  48. def list_bases(
  49. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> list[KnowledgeBaseResponse]:
  50. return [
  51. KnowledgeBaseResponse.from_entity(item)
  52. for item in service.list_bases()
  53. ]
  54. @router.patch("/bases/{knowledge_base_id}/status", response_model=KnowledgeBaseResponse)
  55. def update_base_status(
  56. knowledge_base_id: str,
  57. payload: KnowledgeBaseStatusUpdateRequest,
  58. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> KnowledgeBaseResponse:
  59. entity = service.update_base_status(
  60. knowledge_base_id=knowledge_base_id,
  61. payload=payload)
  62. if entity is None:
  63. raise HTTPException(
  64. status_code=404,
  65. detail=f"knowledge base not found: {knowledge_base_id}")
  66. return KnowledgeBaseResponse.from_entity(entity)
  67. @router.post("/documents", response_model=KnowledgeDocumentIngestResponse)
  68. def create_document(
  69. payload: KnowledgeDocumentCreateRequest,
  70. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> KnowledgeDocumentIngestResponse:
  71. try:
  72. document, chunks = service.create_document(payload)
  73. except ValueError as exc:
  74. raise HTTPException(status_code=422, detail=str(exc)) from exc
  75. return KnowledgeDocumentIngestResponse(
  76. document=KnowledgeDocumentResponse.from_entity(document),
  77. chunks=[KnowledgeChunkResponse.from_entity(item) for item in chunks])
  78. @router.post("/documents/parse", response_model=KnowledgeDocumentParseResponse)
  79. def parse_document(
  80. payload: KnowledgeDocumentParseRequest,
  81. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> KnowledgeDocumentParseResponse:
  82. try:
  83. parsed = service.parse_document(payload)
  84. except DocumentParseError as exc:
  85. raise HTTPException(status_code=422, detail=str(exc)) from exc
  86. return KnowledgeDocumentParseResponse(
  87. content_text=parsed.content_text,
  88. source_type=parsed.source_type,
  89. metadata_json=parsed.metadata_json)
  90. @router.get("/documents", response_model=list[KnowledgeDocumentResponse])
  91. def list_documents(
  92. knowledge_base_id: str = Query(...),
  93. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> list[KnowledgeDocumentResponse]:
  94. return [
  95. KnowledgeDocumentResponse.from_entity(item)
  96. for item in service.list_documents(
  97. knowledge_base_id=knowledge_base_id)
  98. ]
  99. @router.post("/search", response_model=list[KnowledgeSearchResultResponse])
  100. def search(
  101. payload: KnowledgeSearchRequest,
  102. service: KnowledgeApplicationService = Depends(get_knowledge_application_service)) -> list[KnowledgeSearchResultResponse]:
  103. return [
  104. KnowledgeSearchResultResponse(
  105. chunk=KnowledgeChunkResponse.from_entity(chunk),
  106. document=KnowledgeDocumentResponse.from_entity(document),
  107. score=score,
  108. score_json=score_json)
  109. for chunk, document, score, score_json in service.search(payload)
  110. ]