Files
md-vector-db/src/core/splitters/registry.py
T

79 lines
2.4 KiB
Python

"""Splitter 注册表 — 按文件扩展名自动选择分块器."""
from pathlib import Path
from src.core.splitters.base import Splitter
# 扩展名 → Splitter 类名映射
_DEFAULT_MAP: dict[str, str] = {
".md": "markdown",
".markdown": "markdown",
".txt": "text",
".pdf": "pdf",
".html": "html",
".htm": "html",
".epub": "epub",
}
# 所有支持的扩展名集合(供外部遍历文件使用)
SUPPORTED_SUFFIXES = frozenset(_DEFAULT_MAP.keys())
# 用户可注册自定义 Splitter
_custom_registry: dict[str, type[Splitter]] = {}
def register_splitter(ext: str, splitter_cls: type[Splitter]) -> None:
"""注册自定义 Splitter 类.
注意: 此函数非线程安全,请在程序启动时调用(单线程阶段)。
运行时动态注册需自行加锁。
"""
ext = ext.lower() if ext.startswith(".") else f".{ext}"
_custom_registry[ext] = splitter_cls
def get_splitter(
file_path: str,
max_size: int = 1000,
overlap: int = 100,
) -> Splitter:
"""根据文件扩展名自动选择 Splitter,未匹配回退到 TextSplitter.
Args:
file_path: 文件路径(用于提取扩展名)
max_size: 分块最大字符数
overlap: 相邻块重叠字符数
Returns:
对应格式的 Splitter 实例
"""
ext = Path(file_path).suffix.lower()
# 优先查用户自定义注册
if ext in _custom_registry:
return _custom_registry[ext](max_size=max_size, overlap=overlap)
kind = _DEFAULT_MAP.get(ext, "text")
if kind == "markdown":
from src.core.splitters.markdown import MarkdownSplitter
return MarkdownSplitter(max_size=max_size, overlap=overlap)
if kind == "text":
from src.core.splitters.text import TextSplitter
return TextSplitter(max_size=max_size, overlap=overlap)
if kind == "pdf":
from src.core.splitters.pdf import PDFSplitter
return PDFSplitter(max_size=max_size, overlap=overlap)
if kind == "html":
from src.core.splitters.html import HTMLSplitter
return HTMLSplitter(max_size=max_size, overlap=overlap)
if kind == "epub":
from src.core.splitters.epub import EPUBSplitter
return EPUBSplitter(max_size=max_size, overlap=overlap)
# 回退
from src.core.splitters.text import TextSplitter
return TextSplitter(max_size=max_size, overlap=overlap)