ChatwTextwmeta / aimakerspace /text_utils.py
yinong333's picture
Deploying Pythonic RAG
6e5106c
raw
history blame contribute delete
3.31 kB
import os
from typing import List
class TextFileLoader:
def __init__(self, path: str, encoding: str = "utf-8"):
self.documents = []
self.path = path
self.encoding = encoding
self.metadata = [] #added by YL
def load(self):
if os.path.isdir(self.path):
self.load_directory()
elif os.path.isfile(self.path) and self.path.endswith(".txt"):
self.load_file()
else:
raise ValueError(
"Provided path is neither a valid directory nor a .txt file."
)
def load_file(self):
with open(self.path, "r", encoding=self.encoding) as f:
self.documents.append(f.read())
self.metadata.append({"filename": os.path.basename(self.path), "filepath": self.path}) #added by YL
def load_directory(self):
for root, _, files in os.walk(self.path):
for file in files:
if file.endswith(".txt"):
with open(
os.path.join(root, file), "r", encoding=self.encoding
) as f:
self.documents.append(f.read())
def load_documents_with_metadata(self): #changed name
self.load()
#return self.documents
return [{"text": doc, "metadata": meta} for doc, meta in zip(self.documents, self.metadata)] #changed by YL
class CharacterTextSplitter:
def __init__(
self,
chunk_size: int = 1000,
chunk_overlap: int = 200,
):
assert (
chunk_size > chunk_overlap
), "Chunk size must be greater than chunk overlap"
self.chunk_size = chunk_size
self.chunk_overlap = chunk_overlap
# def split(self, text: str) -> List[str]:
# chunks = []
# for i in range(0, len(text), self.chunk_size - self.chunk_overlap):
# chunks.append(text[i : i + self.chunk_size])
# return chunks
#def split_texts(self, texts: List[str]) -> List[str]:
# chunks = []
# for text in texts:
# chunks.extend(self.split(text))
# return chunks
def split(self, text: str, metadata: dict[str, str]) -> List[dict[str, str]]:
chunks = []
for i in range(0, len(text), self.chunk_size - self.chunk_overlap):
chunk = text[i : i + self.chunk_size]
chunk_metadata = metadata.copy()
chunk_metadata["chunk_index"] = i // (self.chunk_size - self.chunk_overlap)
chunks.append({"text": chunk, "metadata": chunk_metadata})
return chunks
def split_texts_with_metadata(
self, documents_with_metadata: List[dict[str, str]]
) -> List[dict[str, str]]:
chunks = []
for document in documents_with_metadata:
chunks.extend(self.split(document["text"], document["metadata"]))
return chunks
if __name__ == "__main__":
loader = TextFileLoader("data/KingLear.txt")
loader.load()
splitter = CharacterTextSplitter()
#chunks = splitter.split_texts(loader.documents)
chunks = splitter.split_texts_with_metadata(loader.documents)
print(len(chunks))
print(chunks[0])
print("--------")
print(chunks[1])
print("--------")
print(chunks[-2])
print("--------")
print(chunks[-1])