Datavision / backend /ingestion /processor.py
DataVision CI/CD Bot
release: clean production build for HuggingFace Space
09801ca
Raw
History Blame Contribute Delete
2.74 kB
# Document processor module
"""
Text processing with support for both fixed-size and semantic chunking.
Default: Semantic chunking for better RAG accuracy.
"""
import re
from typing import List
class Processor:
"""
Document processor with configurable chunking strategy.
Strategies:
- "semantic": Sentence-boundary aware chunking (default, better for RAG)
- "fixed": Fixed-size character chunking (legacy)
"""
def __init__(self, size: int = 700, overlap: int = 150, strategy: str = "semantic"):
"""
Args:
size: Max chunk size in characters
overlap: Overlap size (characters for fixed, sentences for semantic)
strategy: "semantic" or "fixed"
"""
self.size = size
self.overlap = overlap
self.strategy = strategy
# Initialize semantic chunker if needed
self._semantic_chunker = None
if strategy == "semantic":
try:
from ingestion.semantic_chunker import SemanticChunker
self._semantic_chunker = SemanticChunker(
max_chunk_size=size,
min_chunk_size=100,
overlap_sentences=max(1, overlap // 100),
preserve_tables=True
)
except ImportError:
print("⚠️ Semantic chunker not available, using fixed strategy")
self.strategy = "fixed"
@staticmethod
def clean(text: str) -> str:
"""Clean text while preserving paragraph structure"""
# Normalize whitespace but keep paragraph breaks
text = re.sub(r'[ \t]+', ' ', text)
text = re.sub(r'\n{3,}', '\n\n', text)
return text.strip()
def chunk(self, text: str) -> List[str]:
"""
Split text into chunks using configured strategy
Args:
text: Document text to chunk
Returns:
List of text chunks
"""
if not text or not text.strip():
return []
if self.strategy == "semantic" and self._semantic_chunker:
return self._semantic_chunk(text)
else:
return self._fixed_chunk(text)
def _semantic_chunk(self, text: str) -> List[str]:
"""Semantic chunking using sentence boundaries"""
return self._semantic_chunker.chunk_texts(text)
def _fixed_chunk(self, text: str) -> List[str]:
"""Legacy fixed-size chunking"""
chunks = []
start = 0
while start < len(text):
end = start + self.size
chunks.append(text[start:end])
start += self.size - self.overlap
return chunks