Download scripts/ingest_corpus.py from Prabu17/askmydocs: direct link, hf CLI and curl.
- Browser
- Download file 4.1 kB
-
https://huggingface.co/spaces/Prabu17/askmydocs/resolve/main/scripts/ingest_corpus.py
- Command line
-
hf download hf://spaces/Prabu17/askmydocs/scripts/ingest_corpus.py
-
curl -L -o ingest_corpus.py https://huggingface.co/spaces/Prabu17/askmydocs/resolve/main/scripts/ingest_corpus.py
4.1 kB
| """Bulk-ingest the local document corpus into AskMyDocs. | |
| Walks ``data/corpus`` and runs the :class:`IngestionPipeline` for every | |
| supported document (markdown, HTML, PDF, DOCX), which parses -> cleans -> | |
| chunks -> persists to PostgreSQL and indexes into Qdrant + keyword postings. | |
| Usage: | |
| python scripts/ingest_corpus.py [--root data/corpus] [--skip-existing] | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parent.parent | |
| if str(ROOT) not in sys.path: | |
| sys.path.insert(0, str(ROOT)) | |
| from app.db.models import Document # noqa: E402 | |
| from app.db.session import session_scope # noqa: E402 | |
| from app.ingestion.pipeline import IngestionPipeline # noqa: E402 | |
| from sqlalchemy import select # noqa: E402 | |
| SUPPORTED_EXTENSIONS = {".md", ".html", ".pdf", ".docx"} | |
| def doc_id_from_path(file_path: Path) -> str: | |
| """Stable SHA-1 doc ID from the canonical posix path (matches pipeline).""" | |
| return hashlib.sha1(file_path.resolve().as_posix().encode("utf-8")).hexdigest()[:32] | |
| def _collect_files(root: Path) -> list[Path]: | |
| """Return supported corpus files, sorted for deterministic ordering.""" | |
| return sorted( | |
| p | |
| for p in root.rglob("*") | |
| if p.is_file() and p.suffix.lower() in SUPPORTED_EXTENSIONS | |
| ) | |
| def register_document(file_path: Path, title: str) -> str: | |
| """Upsert a Document row (required by the ingestion_jobs FK). Returns doc_id.""" | |
| doc_id = doc_id_from_path(file_path) | |
| with session_scope() as sess: | |
| existing = sess.execute( | |
| select(Document).where(Document.document_id == doc_id) | |
| ).scalar_one_or_none() | |
| if existing is not None: | |
| existing.title = title | |
| return doc_id | |
| fmt = file_path.suffix.lstrip(".").lower() | |
| sess.add( | |
| Document( | |
| document_id=doc_id, | |
| title=title, | |
| module="corpus", | |
| source=str(file_path.resolve()), | |
| format=fmt, | |
| file_size_bytes=file_path.stat().st_size, | |
| ) | |
| ) | |
| sess.commit() | |
| return doc_id | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description="Bulk-ingest the document corpus.") | |
| parser.add_argument( | |
| "--root", | |
| default=str(ROOT / "data" / "corpus"), | |
| help="Corpus root directory (default: data/corpus)", | |
| ) | |
| parser.add_argument( | |
| "--limit", | |
| type=int, | |
| default=0, | |
| help=( | |
| "Ingest at most N documents (0 = no limit). Files are sorted, so " | |
| "the selection is deterministic. Useful on slow CPU where the full " | |
| "corpus would take many minutes." | |
| ), | |
| ) | |
| args = parser.parse_args() | |
| root = Path(args.root) | |
| files = _collect_files(root) | |
| if not files: | |
| print(f"No supported documents found under {root}") | |
| return 1 | |
| if args.limit and args.limit > 0: | |
| files = files[: args.limit] | |
| print(f"Found {len(files)} documents to ingest under {root}") | |
| pipeline = IngestionPipeline() | |
| ok = 0 | |
| failed: list[str] = [] | |
| for i, path in enumerate(files, start=1): | |
| try: | |
| register_document(path, title=path.stem) | |
| print(f"[{i}/{len(files)}] Ingesting {path.name} ...", flush=True) | |
| result = pipeline.ingest(file_path=path, title=path.stem) | |
| print( | |
| f" -> ok doc_id={result.document_id} chunks={result.chunk_count}", | |
| flush=True, | |
| ) | |
| ok += 1 | |
| except Exception as exc: # noqa: BLE001 | |
| print(f" -> FAILED: {exc}", flush=True) | |
| failed.append(f"{path}: {exc}") | |
| print(f"\nDone. Ingested {ok}/{len(files)} documents.") | |
| if failed: | |
| print("Failures:") | |
| for f in failed: | |
| print(" -", f) | |
| return 1 | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |