Spaces:
Sleeping
Sleeping
| """ | |
| Visuals API — Serve Page Images | |
| ================================ | |
| GET /api/visuals/{doc_id}/{page_number} | |
| Returns the rendered PDF page image for display in the UI. | |
| """ | |
| import logging | |
| from pathlib import Path | |
| from fastapi import APIRouter, HTTPException | |
| from fastapi.responses import FileResponse | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter() | |
| BASE_DIR = Path(__file__).parent.parent.parent | |
| DATA_DIR = BASE_DIR / "data" | |
| PAGES_DIR = DATA_DIR / "pages" | |
| def _page_image_candidates(doc_id: str, page_number: int) -> list[Path]: | |
| pages_dir = PAGES_DIR / doc_id / "pages" | |
| page_stem = f"page_{page_number:04d}" | |
| return [ | |
| pages_dir / f"{page_stem}.png", | |
| pages_dir / f"{page_stem}_colpali_index.png", | |
| pages_dir / f"{page_stem}_colpali.png", | |
| ] | |
| async def get_page_image(doc_id: str, page_number: int): | |
| """ | |
| Serve the rendered full-resolution page image for a given document page. | |
| Used by the RightEvidencePanel PDF viewer. | |
| """ | |
| img_path = next( | |
| (candidate for candidate in _page_image_candidates(doc_id, page_number) if candidate.exists()), | |
| None, | |
| ) | |
| if not img_path: | |
| raise HTTPException( | |
| status_code=404, | |
| detail=f"Page image not found: doc={doc_id}, page={page_number}. " | |
| "Run the ingestion script first.", | |
| ) | |
| return FileResponse( | |
| path=str(img_path), | |
| media_type="image/png", | |
| headers={"Cache-Control": "public, max-age=3600"}, | |
| ) | |
| async def get_colpali_image(doc_id: str, page_number: int): | |
| """Serve the image used for ColPali indexing (for debugging).""" | |
| pages_dir = PAGES_DIR / doc_id / "pages" | |
| page_stem = f"page_{page_number:04d}" | |
| img_path = next( | |
| ( | |
| candidate | |
| for candidate in [ | |
| pages_dir / f"{page_stem}_colpali_index.png", | |
| pages_dir / f"{page_stem}_colpali.png", | |
| ] | |
| if candidate.exists() | |
| ), | |
| None, | |
| ) | |
| if not img_path: | |
| raise HTTPException(status_code=404, detail="ColPali image not found") | |
| return FileResponse(str(img_path), media_type="image/png") | |
| async def get_visual_index(doc_id: str): | |
| """Return list of all indexed pages with metadata for a document.""" | |
| index_path = BASE_DIR / "data" / "colpali_index" / doc_id / "colpali_index.json" | |
| if not index_path.exists(): | |
| raise HTTPException(status_code=404, detail=f"No ColPali index for doc '{doc_id}'") | |
| import json | |
| with open(index_path) as f: | |
| records = json.load(f) | |
| return { | |
| "doc_id": doc_id, | |
| "total_pages": len(records), | |
| "pages": [ | |
| { | |
| "page_number": r["page_number"], | |
| "has_embedding": bool(r.get("colpali_embedding_path")), | |
| "image_url": f"/api/visuals/{doc_id}/{r['page_number']}", | |
| } | |
| for r in records | |
| ], | |
| } | |