repair-guy / pipelines /ingest.py
airayven7's picture
Sync from GitHub 7d9b758
436dbdd verified
Raw
History Blame
1.9 kB
"""Ingest pipeline: PDF -> page images -> ColEmbed embeddings -> on-disk store.
Pages are embedded in chunks of EMBED_PAGES_PER_CALL so each ZeroGPU call stays
short; progress is reported between chunks.
"""
from __future__ import annotations
import os
from core.constants import EMBED_PAGES_PER_CALL, RENDER_DPI
from core.pdf import page_count, render_pages
from core.store import Store, slugify
from models.colembed import ColEmbed
class IngestPipeline:
def __init__(self, embedder: ColEmbed, store: Store):
self.embedder = embedder
self.store = store
def run(self, pdf_path: str | None, doc_name: str = "", progress=None) -> dict:
"""Index one PDF; returns the stored doc's summary. Re-indexing a manual
with the same name overwrites it."""
if not pdf_path:
raise ValueError("Please upload a PDF first.")
if not pdf_path.lower().endswith(".pdf"):
raise ValueError("Only PDFs can be indexed.")
name = doc_name.strip() or (
os.path.splitext(os.path.basename(pdf_path))[0].replace("_", " ")
)
doc_id = slugify(name)
total = page_count(pdf_path)
writer = self.store.create(doc_id, name, pdf_path, RENDER_DPI, self.embedder.MODEL_ID)
try:
for start in range(1, total + 1, EMBED_PAGES_PER_CALL):
nums = list(range(start, min(start + EMBED_PAGES_PER_CALL, total + 1)))
images = render_pages(pdf_path, nums)
for num, emb in zip(nums, self.embedder.embed_pages(images)):
writer.add_page(num, emb)
if progress:
progress(nums[-1] / total, f"Embedded {nums[-1]}/{total} pages")
writer.finalize()
except BaseException:
writer.abort()
raise
return {"doc_id": doc_id, "name": name, "pages": total}