Skip to main content

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-transformers is included by default. The all-MiniLM-L6-v2 model (~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)

Pluggable Vector Databases

By default, raglite uses a lightweight in-memory vector store that persists indexes locally to JSON files. You can swap it out for a local or cloud-backed vector database by passing vectorStore in the options dict.

Memory Store (Default)

doc = Document("./policy.pdf", {
    "vectorStore": {"provider": "memory", "storeDir": ".raglite"},
})

Qdrant (Local or Cloud)

Supports local Docker instances and Qdrant Cloud clusters.

doc = Document("./policy.pdf", {
    "embeddings": {"provider": "local"},
    "vectorStore": {
        "provider": "qdrant",
        "url": "http://localhost:6333",   # or Qdrant Cloud URL
        "apiKey": "your-qdrant-api-key",  # optional
        "indexName": "my_collection",     # optional
    },
})

Pinecone (Cloud)

Scopes collections using Pinecone's native namespaces.

doc = Document("./policy.pdf", {
    "embeddings": {"provider": "openai", "apiKey": "sk-..."},
    "vectorStore": {
        "provider": "pinecone",
        "url": "https://your-index-host.svc.pinecone.io",
        "apiKey": "your-pinecone-api-key",
    },
})

Custom Vector Store Class

Implement the VectorStore ABC and pass an instance directly.

from raglite.vectordb.base import VectorStore, VectorSearchHit
from raglite.types import IndexMetadata, StoredChunk

class MyStore(VectorStore):
    # Implement: load, reset, add, search, count,
    #            save_index_metadata, read_index_metadata
    ...

doc = Document("./policy.pdf", {
    "vectorStore": MyStore(),
})

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 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 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

raglite_toolkit-1.1.0.tar.gz (44.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

raglite_toolkit-1.1.0-py3-none-any.whl (39.7 kB view details)

Uploaded Python 3

File details

Details for the file raglite_toolkit-1.1.0.tar.gz.

File metadata

  • Download URL: raglite_toolkit-1.1.0.tar.gz
  • Upload date:
  • Size: 44.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raglite_toolkit-1.1.0.tar.gz
Algorithm Hash digest
SHA256 2b2562168f01b3c03b2e2bb84cf719c6181416d35d2a195c34c04f5be73cd096
MD5 8d6f145a0613f4f5b20c2d5cf08b79ea
BLAKE2b-256 29e78be67d0c5f41d930b70eb0f379966ced58552012056f480f26c8dce19c44

See more details on using hashes here.

Provenance

The following attestation bundles were made for raglite_toolkit-1.1.0.tar.gz:

Publisher: publish.yml on creatorpiyush/raglite-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file raglite_toolkit-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: raglite_toolkit-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for raglite_toolkit-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0c93fa450dffab441d68093baaece5d3375eeb97db300685332a77ad68f7db8e
MD5 5661a1f9fdd8ab9b16e9f6530bbb7adf
BLAKE2b-256 e9f627c19ec4e11714727b2ab980a47ac69f917b29174f5d285e3d112de4f20f

See more details on using hashes here.

Provenance

The following attestation bundles were made for raglite_toolkit-1.1.0-py3-none-any.whl:

Publisher: publish.yml on creatorpiyush/raglite-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page