Files
chunking_strategies_evaluation/src/documents/routes.py
Mahdi Bazrafshan cbaa72b420 feat(documents): add GET /documents endpoint and improve models
Why:
- Need to list documents to get document IDs for queries
- ProcessRequest should default to all 5 strategies
- paragraph_count should be optional (not always stored)

Changes:
- Added GET /documents endpoint with pagination
- Added DocumentListResponse model
- ProcessRequest now defaults to all 5 strategies
- DocumentResponse.paragraph_count now defaults to 0
2026-07-26 12:06:14 +03:30

85 lines
2.9 KiB
Python

"""Document and strategy API routes.
Endpoints:
POST /documents Upload a .docx file
POST /documents/{id}/process Run chunking strategies (stub until Phase 2)
DELETE /documents/{id} Remove document + vectors
GET /strategies List available chunking strategies
"""
from fastapi import APIRouter, File, UploadFile
from src.core.exceptions import DocumentProcessingError
from src.core.models import PaginatedResponse, StrategyName
from src.documents.models import (
DeleteResponse,
DocumentResponse,
DocumentListResponse,
ProcessRequest,
ProcessResponse,
StrategiesResponse,
StrategyInfo,
)
from src.documents import service
router = APIRouter()
@router.get("/documents", response_model=DocumentListResponse)
async def list_documents(offset: int = 0, limit: int = 50):
"""List all uploaded documents with pagination."""
result = service.list_documents(offset=offset, limit=limit)
return DocumentListResponse(
items=[DocumentResponse(**doc) for doc in result["items"]],
total=result["total"],
offset=result["offset"],
limit=result["limit"],
)
@router.post("/documents", response_model=DocumentResponse, status_code=201)
async def upload_document(file: UploadFile = File(...)):
"""Upload a .docx file. Parses it, stores the document tree in SQLite."""
if not file.filename:
raise DocumentProcessingError("No filename provided")
if not file.filename.lower().endswith((".docx", ".doc")):
raise DocumentProcessingError("Only .docx and .doc files are supported")
content = await file.read()
if not content:
raise DocumentProcessingError("Empty file")
doc = service.upload_document(file.filename, content)
return DocumentResponse(
id=doc["id"],
filename=doc["filename"],
paragraph_count=doc.get("paragraph_count", 0),
chunk_counts=doc.get("chunk_counts", {}),
created_at=doc["created_at"],
)
@router.post("/documents/{doc_id}/process", response_model=ProcessResponse)
async def process_document(doc_id: str, request: ProcessRequest):
"""Run selected chunking strategies on an uploaded document.
Currently returns stub results until Phase 2 implements the strategies.
"""
return service.process_document(doc_id, request)
@router.delete("/documents/{doc_id}", response_model=DeleteResponse)
async def delete_document(doc_id: str):
"""Delete a document and all its chunk vectors from Qdrant."""
deleted = service.delete_document(doc_id)
return DeleteResponse(deleted=deleted, document_id=doc_id)
@router.get("/strategies", response_model=StrategiesResponse)
async def list_strategies():
"""List available chunking strategies with descriptions."""
strategies = service.list_strategies()
return StrategiesResponse(
strategies=[StrategyInfo(**s) for s in strategies]
)