Skip to content

Ingest anything

Ingest a file, raw text, or a URL. Python’s ingest() writes into a persistent store and is idempotent by content hash. Go and JavaScript have no store on the plain go get / npm install surface, so they do the same job in memory: turn a source into chunked corpus documents and pass that corpus to Ask / ask.

from citenexus.extract.types import SourceType
rag.ingest("report.pdf") # a file → extractor picked by extension
rag.ingest(text="Clause 4: 90 days notice.", document_id="c4") # raw text (plain)
rag.ingest("https://example.com/policy") # a URL → fetched, HTML-extracted
rag.ingest(image_bytes, source_type=SourceType.image, document_id="fig-1") # an image
r = rag.ingest("corpus/nda.txt")
print(r.status, r.n_units) # "ingested" 1 (or "unchanged" 0 on a re-ingest)
print(r.document_id, r.eu_ids) # "nda" ('nda::0::0',)

Re-ingesting the same document_id with identical bytes is a no-op:

rag.ingest(text="Clause 4: 90 days notice.", document_id="c4").status # "ingested"
rag.ingest(text="Clause 4: 90 days notice.", document_id="c4").status # "unchanged"

Ingest has an inverse: rag.delete(document_id) (alias revoke) surgically removes one document and everything derived from it — idempotently, and guarding raw blobs shared by identical bytes.

crawl() does a same-domain breadth-first walk, ingesting each page as HTML:

results = rag.crawl("https://docs.example.com", max_pages=50, max_depth=3)
print(len(results), "pages ingested")

Extraction dispatches by explicit source_type first, then file extension, then falls back to plain text:

Extension Extractor
.pdf PDF (text + figures, with page and — at extraction only — bbox)
.docx .pptx .xlsx Office (OOXML); tables become GFM Markdown
.html .htm HTML
.md .markdown Markdown
.csv CSV
.txt Plain text
anything else Plain-text fallback — never a hard failure

Which indexes get built from the extracted units is governed by the signals you declared.