Build semantic search, multi-provider question answering, and REST APIs over your documents in a few lines of Python.
Project description
raglite-toolkit
Build semantic search, multi-provider question answering, and REST APIs over your documents in a few lines of Python.
raglite-toolkit is a Python port of the raglite-toolkit TypeScript package with full feature parity.
Features
- ๐ PDF, TXT, JSON, Markdown, DOCX loaders out of the box
- ๐ค 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)
Fully Offline โ No API Key Needed
from raglite import Document
doc = Document("./policy.pdf", {
"embeddings": {"provider": "local"}, # sentence-transformers offline
"llm": {"provider": "ollama", # local Ollama instance
"model": "llama3.2",
"baseURL": "http://localhost:11434/api"},
})
doc.build()
print(doc.ask("What is the refund policy?").text)
Choose Any LLM at Ask-Time
# Switch LLMs without rebuilding the index โ embeddings are reused
for llm in [
{"provider": "openai", "model": "gpt-4o", "apiKey": "sk-..."},
{"provider": "anthropic", "model": "claude-3-5-sonnet-20241022","apiKey": "sk-ant-..."},
{"provider": "google", "model": "gemini-2.0-flash", "apiKey": "AI..."},
{"provider": "groq", "model": "llama-3.3-70b-versatile", "apiKey": "gsk_..."},
]:
answer = doc.ask("Summarize this document", {"llm": llm})
print(f"[{llm['provider']}] {answer.text[:120]}")
Streaming
for chunk in doc.ask_stream("Explain the introduction"):
print(chunk, end="", flush=True)
REST API
handle = doc.serve({
"port": 8085,
"llm": {"provider": "openai", "apiKey": "sk-..."},
"bearerToken": "my-secret-token",
})
print(f"Serving on {handle.url}")
# ... later
handle.close()
Endpoints
| Method | Path | Auth? | Description |
|---|---|---|---|
GET |
/health |
โ | Liveness + index stats |
GET |
/info |
โ | Configuration snapshot |
POST |
/search |
โ | Semantic search |
POST |
/ask |
โ | Question answering |
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 my-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 my-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 my-secret-token' \
-H 'Content-Type: application/json' \
-d '{"question": "Summarize the document", "stream": true}'
CLI
# Index a document
raglite index ./policy.pdf --embed-provider local
# Semantic search
raglite search ./policy.pdf "refund policy" --top-k 5
# Ask a question (streaming)
raglite ask ./policy.pdf "What is the refund policy?" \
--llm-provider openai --llm-key $OPENAI_API_KEY --stream
# Serve a REST API
raglite serve ./policy.pdf \
--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 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 |
| Library version | Package version bumped |
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: 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 <repo>
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 tests (76 tests, ~5s, no network required)
pytest
# Run with coverage
pytest --cov=raglite --cov-report=term-missing
# Run examples (uses local offline embeddings)
python examples/basic.py
python examples/multi_provider.py # requires API keys in env
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_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_ask.py # ask/stream with mocked LLM generation
โโโ test_api.py # FastAPI endpoints via TestClient
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file raglite_toolkit-1.0.1.tar.gz.
File metadata
- Download URL: raglite_toolkit-1.0.1.tar.gz
- Upload date:
- Size: 37.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
749eb3d48725d7d71748e5e83a984aeffcbf83995840f62cc6a34f7c86bed14f
|
|
| MD5 |
cc3684e1cec4785a3039461029a9eeb5
|
|
| BLAKE2b-256 |
12e051fe5fb8e362f02d7df0344cfebe0f1c0eb16b0703726cd88d4f6402b990
|
Provenance
The following attestation bundles were made for raglite_toolkit-1.0.1.tar.gz:
Publisher:
publish.yml on creatorpiyush/raglite-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
raglite_toolkit-1.0.1.tar.gz -
Subject digest:
749eb3d48725d7d71748e5e83a984aeffcbf83995840f62cc6a34f7c86bed14f - Sigstore transparency entry: 2194630919
- Sigstore integration time:
-
Permalink:
creatorpiyush/raglite-py@2c13e328315261b9a30b1925564f8e0a4ff45295 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/creatorpiyush
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c13e328315261b9a30b1925564f8e0a4ff45295 -
Trigger Event:
push
-
Statement type:
File details
Details for the file raglite_toolkit-1.0.1-py3-none-any.whl.
File metadata
- Download URL: raglite_toolkit-1.0.1-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa8f784ffccdcf667661c825f2a1bf28e888fa25907f7f2d1acc6862fa1bcd2a
|
|
| MD5 |
5b165f643546834e3b6e3bb7cfedc1dc
|
|
| BLAKE2b-256 |
49fc267f486dc39d658077ac9082f3cf37cf0442c608bfad3c2ab22cb997f0c5
|
Provenance
The following attestation bundles were made for raglite_toolkit-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on creatorpiyush/raglite-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
raglite_toolkit-1.0.1-py3-none-any.whl -
Subject digest:
aa8f784ffccdcf667661c825f2a1bf28e888fa25907f7f2d1acc6862fa1bcd2a - Sigstore transparency entry: 2194630985
- Sigstore integration time:
-
Permalink:
creatorpiyush/raglite-py@2c13e328315261b9a30b1925564f8e0a4ff45295 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/creatorpiyush
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c13e328315261b9a30b1925564f8e0a4ff45295 -
Trigger Event:
push
-
Statement type: