raglite-toolkit
Build semantic search, multi-provider question answering, and REST APIs over your documents, directories, or web URLs in a few lines of Python.
raglite-toolkit is a Python port of the raglite-toolkit TypeScript package with full 1:1 feature parity.
Features
- 📄 PDF, TXT, JSON, Markdown, DOCX loaders out of the box
- 📁 Multi-document, directory, & URL ingestion — index folders, glob patterns, or web URLs with
DocumentCollection - 🤖 Multi-provider LLMs — OpenAI, Anthropic (Claude), Google (Gemini), Mistral, Cohere, Groq, xAI, Ollama
- 🔢 Multi-provider embeddings — OpenAI, Google, Mistral, Cohere, Voyage, Ollama, or a local offline sentence-transformer (no API key needed)
- 📐 Cosine similarity scoring with L2-normalized vectors
- ♻️ Content-hash cache — reindexes only when the file actually changes
- 🗂 Per-document namespacing — indexes are isolated, two documents never collide
- 🌐 REST API via FastAPI with optional bearer-token auth
- ⚡ Streaming answers
- 🐍 Python-native — Pydantic models, type-annotated, fully testable
Install
pip install raglite-toolkit
For local offline embeddings (no API key required):
pip install raglite-toolkit sentence-transformers
sentence-transformersis included by default. Theall-MiniLM-L6-v2model (~90 MB) is downloaded automatically on first use.
Quick Start
from raglite import Document
doc = Document("./policy.pdf", {
"embeddings": {"provider": "openai", "apiKey": "sk-..."},
"llm": {"provider": "anthropic", "apiKey": "sk-ant-..."},
})
doc.build() # chunk → embed → persist
hits = doc.search("refund policy", top_k=3)
answer = doc.ask("What is the refund policy?")
print(answer.text)
Multi-Document & Directory Ingestion (DocumentCollection)
Index entire directories (./docs), glob patterns, web URLs, or mixed file arrays:
from raglite import DocumentCollection
collection = DocumentCollection(["./docs", "https://example.com"], {
"embeddings": {"provider": "local"},
"llm": {"provider": "openai", "apiKey": "sk-..."},
})
# Index all documents concurrently
result = collection.build()
print(f"Indexed {result.totalDocuments} document(s), {result.totalChunks} chunk(s).")
# Search across all collection documents simultaneously
hits = collection.search("refund policy", top_k=5)
# Contextual Q&A across the entire collection
answer = collection.ask("What is the refund policy?")
print(answer.text)
Fully Offline — No API Key Needed
from raglite import Document
doc = Document("./manual.txt", {
"embeddings": {"provider": "local"},
"llm": {"provider": "ollama", "model": "llama3.2"},
})
doc.build()
print(doc.ask("How do I reset the device?").text)
Choose Any LLM at Ask-Time
# Pass an inline LLM override to ask()
gpt4 = doc.ask("Summarise this document", options={
"llm": {"provider": "openai", "model": "gpt-4o", "apiKey": "sk-..."}
})
claude = doc.ask("Summarise this document", options={
"llm": {"provider": "anthropic", "model": "claude-3-5-sonnet-20241022", "apiKey": "sk-ant-..."}
})
Streaming Responses
for chunk in doc.ask_stream("Explain section 3 in detail"):
print(chunk, end="", flush=True)
print()
Pluggable Vector Databases
raglite supports pluggable vector stores (Memory, Qdrant, Pinecone, or custom subclasses; LanceDB is currently TypeScript-only):
Memory Store (Default)
doc = Document("./policy.pdf", {
"vectorStore": {"provider": "memory", "storeDir": ".raglite"}
})
Qdrant Store
By default each document gets its own collection (raglite_<namespace>). Set indexName to keep several documents in one shared collection; each document's points are tagged with its namespace, so rebuilding one document never affects the others.
doc = Document("./policy.pdf", {
"vectorStore": {
"provider": "qdrant",
"url": "http://localhost:6333",
"apiKey": "your-key",
"indexName": "my_collection"
}
})
Pinecone Store
doc = Document("./policy.pdf", {
"vectorStore": {
"provider": "pinecone",
"url": "https://my-index.svc.pinecone.io",
"apiKey": "your-key"
}
})
REST API
from raglite import Document
doc = Document("./policy.pdf", {
"embeddings": {"provider": "local"},
"llm": {"provider": "openai", "apiKey": "sk-..."},
})
doc.build()
# Start background FastAPI server on port 8085
doc.serve(port=8085, bearer_token="secret-token")
Endpoints:
| Method | Path | Auth required? | Description |
|---|---|---|---|
GET |
/health |
❌ | Liveness + index stats |
GET |
/info |
✅ | Configuration snapshot |
POST |
/search |
✅ | Semantic search |
POST |
/ask |
✅ | Question answering (supports stream: true) |
Example curl calls
# Health check (no auth)
curl http://127.0.0.1:8085/health
# Search
curl -X POST http://127.0.0.1:8085/search \
-H 'Authorization: Bearer secret-token' \
-H 'Content-Type: application/json' \
-d '{"query": "refund policy", "topK": 3}'
# Ask (non-streaming)
curl -X POST http://127.0.0.1:8085/ask \
-H 'Authorization: Bearer secret-token' \
-H 'Content-Type: application/json' \
-d '{"question": "What is the refund policy?"}'
# Ask (streaming)
curl -X POST http://127.0.0.1:8085/ask \
-H 'Authorization: Bearer secret-token' \
-H 'Content-Type: application/json' \
-d '{"question": "Summarize the document", "stream": true}'
CLI
# Index a document, directory, or URL
raglite index ./policy.pdf --embed-provider local
# Semantic search
raglite search ./docs "refund policy" --top-k 5
# Ask a question (streaming)
raglite ask ./docs "What is the refund policy?" \
--llm-provider anthropic --llm-key $ANTHROPIC_API_KEY --stream
# Serve a REST API
raglite serve https://example.com \
--llm-provider openai --llm-key $OPENAI_API_KEY \
--port 8085 --token $RAGLITE_TOKEN
Supported Providers
LLMs
| Provider | provider key |
Default model |
|---|---|---|
| OpenAI | openai |
gpt-4o-mini |
| Anthropic | anthropic |
claude-3-5-sonnet-20241022 |
google |
gemini-2.0-flash |
|
| Mistral | mistral |
mistral-large-latest |
| Cohere | cohere |
command-r-plus |
| Groq | groq |
llama-3.3-70b-versatile |
| xAI (Grok) | xai |
grok-2-latest |
| Ollama (local) | ollama |
llama3.2 |
Embeddings
| Provider | provider key |
Default model |
|---|---|---|
| OpenAI | openai |
text-embedding-3-small |
google |
text-embedding-004 |
|
| Mistral | mistral |
mistral-embed |
| Cohere | cohere |
embed-english-v3.0 |
| Voyage | voyage |
voyage-3 |
| Ollama (local) | ollama |
nomic-embed-text |
| Local (offline) | local |
all-MiniLM-L6-v2 |
Configuration Reference
Document("./policy.pdf", {
# Chunking
"chunkSize": 500, # words per chunk (default: 500)
"overlap": 50, # overlapping words between chunks (default: 50)
# Retrieval
"topK": 5, # default results returned (default: 5)
"scoreThreshold": 0.0, # minimum cosine similarity (0..1, default: 0)
# Storage
"storeDir": ".raglite", # where indexes are persisted (default: .raglite)
# Providers
"embeddings": {"provider": "local"},
"llm": {"provider": "openai", "model": "gpt-4o-mini", "apiKey": "sk-..."},
# Logging
"logLevel": "info", # "silent" | "info" | "debug" (default: info)
})
How Caching Works
Every build() call fingerprints the source (file bytes, or the fetched text for URLs) with a SHA-256 content hash and persists it alongside the vectors. The cached index is reused only if all of the following match the stored index:
| Factor | Triggers rebuild if changed |
|---|---|
| File content | SHA-256 hash differs |
| Chunk size | chunkSize changed |
| Overlap | overlap changed |
| Embedding provider/model | Provider or model string changed |
| Index format | Stored index layout changed by a release (rare; ordinary upgrades reuse the index) |
Pass rebuild=True to build() to force a fresh index regardless.
Each document is stored under .raglite/<sha256-prefix>/, so multiple documents in the same project never overwrite each other.
Advanced Usage
Custom Vector Store
from raglite.vectordb.base import VectorStore
class MyVectorStore(VectorStore):
# Implement: namespace (property), load, reset, add, search, count,
# save_index_metadata, read_index_metadata
...
Custom Loader
from raglite.loaders.base import BaseLoader
from raglite.loaders import get_loader
class CsvLoader(BaseLoader):
def load(self) -> str:
# read CSV, return string
...
Custom Chunker
from raglite.chunking.base import BaseChunker
class SentenceChunker(BaseChunker):
def split(self, text: str) -> list[str]:
...
Direct Embedder Access
from raglite import create_embedder
embedder = create_embedder({"provider": "openai", "apiKey": "sk-..."})
vectors = embedder.embed_documents(["chunk one", "chunk two"])
query_vec = embedder.embed_query("refund policy")
Development
# Clone and set up
git clone https://github.com/creatorpiyush/raglite-py.git
cd raglite-py
# Create virtual environment
python3.12 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run test suite
pytest
# Run with coverage
pytest --cov=raglite --cov-report=term-missing
# Run examples
python examples/basic.py
python examples/serve.py
Test Structure
tests/
├── unit/
│ ├── test_chunking.py # RecursiveChunker algorithm
│ ├── test_vectordb.py # MemoryVectorStore (cosine, persistence, isolation)
│ ├── test_loaders.py # TxtLoader, MarkdownLoader, JsonLoader
│ ├── test_directory_loader.py # DirectoryLoader (recursive scanning, glob filtering)
│ ├── test_web_loader.py # WebLoader (HTML parsing, tag stripping)
│ ├── test_prompt.py # system/user prompt builders
│ ├── test_errors.py # exception hierarchy
│ ├── test_config.py # config defaults and overrides
│ ├── test_hash.py # SHA-256 file hashing + namespace generation
│ ├── test_retriever.py # Retriever with mocked embedder
│ └── test_cli.py # CLI commands and argument parsing
└── integration/
├── test_document.py # build/cache/search lifecycle (mocked embeddings)
├── test_collection.py # DocumentCollection multi-document indexing & FastAPI server
├── test_ask.py # ask/stream with mocked LLM generation
└── test_api.py # FastAPI endpoints via TestClient
License
MIT © Piyush Anand
Metadata
Release files for raglite-toolkit 1.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| raglite_toolkit-1.2.2.tar.gz | 60.2 kB | With provenance | Details for raglite_toolkit-1.2.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| raglite_toolkit-1.2.2-py3-none-any.whl | Python 3 | none | any | Details for raglite_toolkit-1.2.2-py3-none-any.whl |
Total release size: 107.5 kB
Release files / raglite_toolkit-1.2.2.tar.gz
| Download URL | raglite_toolkit-1.2.2.tar.gz |
|---|---|
| Size | 60.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2fd0c30a8518e7f3ba5e235fdbbae4ca43e4f46e894c6398fbaf8e530a331d61
|
|
BLAKE2b-256 checksum How to use checksums |
95732c748b2cc125ac04b72145eb978f6f909f5dc4f04b2c61eea3aed307672b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / raglite_toolkit-1.2.2-py3-none-any.whl
| Download URL | raglite_toolkit-1.2.2-py3-none-any.whl |
|---|---|
| Size | 47.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9c5884288ad6a6f86b98067d1545a2f9a9e65440c5189a07ca40270c9fcf63ae
|
|
BLAKE2b-256 checksum How to use checksums |
874d2c1de4e02b62483eaa8800f7ad7f5503ad93a8c4e1b885d9895dc36f131e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logSecurity for raglite-toolkit 1.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for raglite_toolkit-1.2.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.