rag_prep
A minimal, extensible framework for preparing documents for RAG/LLM workflows.
Pipeline: load → normalize → chunk → emit
Design Philosophy
- Simple, orthogonal building blocks - Each component has a clear, single responsibility
- Clear interfaces for extensibility - Protocols and ABCs make it easy to plug in custom implementations
- Sensible defaults with freedom to override - Works out of the box, but nothing is hardcoded
- Python API first - CLI is a thin wrapper over the Python API
Installation
pip install rag-prep
For optional file format support:
# PDF support
pip install rag-prep[pdf]
# DOCX support
pip install rag-prep[docx]
# HTML support
pip install rag-prep[html]
# All optional dependencies
pip install rag-prep[all]
Quick Start
Python API
The source path can be a single file or a directory; directories are walked recursively by default, respecting include/exclude filters.
from rag_prep import prepare_docs, prepare_docs_to_jsonl, Config
# Simple usage with defaults
prepare_docs_to_jsonl("document.txt", "output.jsonl")
# With custom configuration
config = Config(
chunk_strategy="token",
chunk_size=500,
chunk_overlap=100,
tokenizer_name="cl100k_base",
)
prepare_docs_to_jsonl("document.txt", "output.jsonl", config=config)
# Get chunks as iterator (for custom processing)
for chunk in prepare_docs("document.txt", config=config):
print(chunk.text)
print(chunk.metadata)
CLI
# Basic usage
rag-prep document.txt -o output.jsonl
# With custom chunking
rag-prep document.txt -o output.jsonl \
--chunk-strategy token \
--chunk-size 500 \
--chunk-overlap 100
# Process directory with filters
rag-prep ./documents -o output.jsonl \
--include "*.txt" "*.md" \
--exclude "*.tmp" \
--chunk-strategy sentence
# Verbose output
rag-prep document.txt -o output.jsonl -v
Extension Points
1. Custom Chunking Strategies
Create a custom chunker by implementing the ChunkingStrategy protocol:
from typing import Iterator
from rag_prep.models import Chunk
from rag_prep.chunkers import ChunkingStrategy
class MyCustomChunker:
def __init__(self, size: int = 1000, overlap: int = 200):
self.size = size
self.overlap = overlap
def chunk(self, text: str, metadata: dict) -> Iterator[Chunk]:
# Your custom chunking logic
# ...
yield Chunk(text=chunk_text, metadata=chunk_metadata, chunk_id="custom_id")
Use it in Python:
from rag_prep import prepare_docs, Config
config = Config(chunk_strategy="character") # Will use your chunker if registered
chunker = MyCustomChunker(size=500)
chunks = prepare_docs("doc.txt", config=config, chunker=chunker)
Or via CLI with module path:
rag-prep doc.txt -o out.jsonl --chunk-strategy mypackage.MyCustomChunker
2. Custom Loaders
Register a loader for a new file type:
from rag_prep.loaders import register_loader
from rag_prep.models import Chunk
from pathlib import Path
class JSONLoader:
def load(self, source):
import json
path = Path(source)
with open(path, 'r') as f:
data = json.load(f)
# Convert to Chunk objects
yield Chunk(
text=str(data),
metadata={"source": str(path), "file_type": "json"},
chunk_id=str(path)
)
# Register for .json files
register_loader(".json", JSONLoader())
3. Custom Output Sinks
Implement the Sink protocol:
from rag_prep.sinks import Sink
from rag_prep.models import Chunk
from typing import Iterator
class DatabaseSink:
def write(self, chunks: Iterator[Chunk]):
# Write chunks to your database
for chunk in chunks:
# ... insert into database
pass
4. Metadata Enrichment
Add metadata hooks to enrich chunks:
from rag_prep import Config, prepare_docs
def add_timestamp(metadata: dict, text: str) -> dict:
import datetime
metadata["processed_at"] = datetime.datetime.now().isoformat()
return metadata
config = Config(metadata_hooks=[add_timestamp])
chunks = prepare_docs("doc.txt", config=config)
5. Custom Tokenizers
Inject your own tokenizer:
from rag_prep import prepare_docs, Config
from rag_prep.tokenizers import Tokenizer
class MyTokenizer:
def encode(self, text: str) -> list:
# Your encoding logic
return tokens
def decode(self, tokens: list) -> str:
# Your decoding logic
return text
tokenizer = MyTokenizer()
config = Config(chunk_strategy="token")
chunks = prepare_docs("doc.txt", config=config, tokenizer=tokenizer)
Built-in Features
Chunking Strategies
character- Character-based chunking (default)token- Token-based chunking (requires tokenizer). If you choose a token-based strategy without providing a tokenizer, rag_prep will use its default tokenizer if available, otherwise it will raise a clear error.sentence- Sentence-aware chunkingnone- No chunking (entire document as single chunk)
Supported File Types
.txt- Plain text.md,.markdown- Markdown.pdf- PDF (requiresrag-prep[pdf]).docx- Word documents (requiresrag-prep[docx]).html,.htm- HTML (requiresrag-prep[html]).csv- CSV files (each row becomes a document)
Output Format
Default output is JSONL (JSON Lines), where each line is a chunk:
{"text": "chunk text...", "metadata": {"source_id": "doc.txt", "chunk_index": 0}, "chunk_id": "doc.txt_chunk_0"}
{"text": "next chunk...", "metadata": {"source_id": "doc.txt", "chunk_index": 1}, "chunk_id": "doc.txt_chunk_1"}
Use Cases
- Prepare a docs/ folder for ingestion into a vector database - Process entire directories of mixed file types into chunked JSONL format ready for embedding and indexing.
- Convert mixed PDFs + DOCX + markdown into JSONL for RAG - Handle diverse document formats and output a standardized chunked format for retrieval-augmented generation pipelines.
- Generate chunked datasets suitable for fine-tuning or eval - Create properly chunked datasets with metadata for training or evaluating language models.
- Stream processing for large document collections - Use iterator-based processing to handle large directories without loading everything into memory.
Architecture
rag_prep/
├── models.py # Chunk, Config data models
├── chunkers.py # Chunking strategies (Protocol + implementations)
├── loaders.py # Document loaders (registry pattern)
├── sinks.py # Output sinks (Protocol + implementations)
├── tokenizers.py # Tokenization backend (Protocol + tiktoken)
├── pipeline.py # Main prepare_docs() API
└── cli.py # Command-line interface
License
MIT
Metadata
Release files for rag-prep 0.1.4
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 |
|---|---|---|---|---|
| rag_prep-0.1.4.tar.gz | 22.3 kB | Without provenance | Details for rag_prep-0.1.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rag_prep-0.1.4-py3-none-any.whl | Python 3 | none | any | Details for rag_prep-0.1.4-py3-none-any.whl |
Total release size: 36.9 kB
Release files / rag_prep-0.1.4.tar.gz
| Download URL | rag_prep-0.1.4.tar.gz |
|---|---|
| Size | 22.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5e3229274dc7afa32bbf84d43f390781b429d8bb2981642a1c01133b23fef94d
|
|
BLAKE2b-256 checksum How to use checksums |
8e7b50e895bd587b09d3d2abbb1c749190a65b259b26763f61f84e182137d2e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / rag_prep-0.1.4-py3-none-any.whl
| Download URL | rag_prep-0.1.4-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e513e1204464187a7102347a1fddddbb4630237e4e32c2ff8e41b2120aefb653
|
|
BLAKE2b-256 checksum How to use checksums |
fe2f4fe88bc8b33fd95db0dcfd0ee4aadd25c8252a52374c6437f00b647ad465
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for rag-prep 0.1.4
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.