singhankur01 commited on
Commit
1e72b5a
·
verified ·
1 Parent(s): d8d5d9c

Update utils/DocsLoader.py

Browse files
Files changed (1) hide show
  1. utils/DocsLoader.py +17 -109
utils/DocsLoader.py CHANGED
@@ -1,116 +1,28 @@
1
- # import os
2
- # import tempfile
3
- # import requests
4
-
5
- # from fastapi import HTTPException
6
- # # from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader
7
- # from langchain_community.document_loaders import PyMuPDFLoader, Docx2txtLoader
8
- # from langchain.text_splitter import RecursiveCharacterTextSplitter
9
- # from langchain_text_splitters.sentence_transformers import SentenceTransformersTokenTextSplitter # give better results but slow can use later for project
10
- # from langchain.schema import Document
11
-
12
- # MODEL_DIR = os.path.join("/tmp", "e5-large-v2")
13
-
14
- # def load_and_chunk(url: str) -> list[Document]:
15
- # print(url)
16
- # resp = requests.get(url)
17
- # if resp.status_code != 200:
18
- # raise HTTPException(400, "Could not download document")
19
-
20
- # content_type = resp.headers.get("Content-Type", "").lower()
21
- # url_lower = url.lower()
22
-
23
- # if "application/pdf" in content_type or ".pdf" in url_lower:
24
- # with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
25
- # tmp.write(resp.content)
26
- # tmp_path = tmp.name
27
- # try:
28
- # loader = PyMuPDFLoader(tmp_path)
29
- # docs = loader.load_and_split()
30
- # finally:
31
- # os.remove(tmp_path)
32
-
33
- # elif (
34
- # "application/vnd.openxmlformats-officedocument.wordprocessingml.document" in content_type
35
- # or ".docx" in url_lower
36
- # ):
37
- # with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp:
38
- # tmp.write(resp.content)
39
- # tmp_path = tmp.name
40
- # try:
41
- # loader = Docx2txtLoader(tmp_path)
42
- # docs = loader.load_and_split()
43
- # finally:
44
- # os.remove(tmp_path)
45
-
46
- # elif "text/plain" in content_type or ".txt" in url_lower:
47
- # text = resp.content.decode("utf-8", errors="ignore")
48
- # docs = [Document(page_content=text)]
49
-
50
- # else:
51
- # raise HTTPException(400, f"Unsupported document type: {content_type}")
52
-
53
- # # splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=120,separators=["\n\n", "\n", ".", " ", ""])
54
- # splitter = SentenceTransformersTokenTextSplitter(model_name = MODEL_DIR,tokens_per_chunk=500, chunk_overlap=80)
55
- # return splitter.split_documents(docs)
56
-
57
  import os
58
  import tempfile
59
  import requests
60
- import hashlib
61
- import pickle
62
 
63
  from fastapi import HTTPException
 
64
  from langchain_community.document_loaders import PyMuPDFLoader, Docx2txtLoader
 
 
65
  from langchain.schema import Document
66
- from langchain_text_splitters.sentence_transformers import SentenceTransformersTokenTextSplitter # better but slower
67
 
68
  MODEL_DIR = os.path.join("/tmp", "e5-large-v2")
69
- CACHE_DIR = os.path.join("/tmp", "chunk_data")
70
- os.makedirs(CACHE_DIR, exist_ok=True)
71
 
72
  def load_and_chunk(url: str) -> list[Document]:
73
- print(f"[Loader] URL: {url}")
 
 
 
74
 
75
- # Try to get content length
76
- try:
77
- head = requests.head(url)
78
- file_size = int(head.headers.get("Content-Length", 0))
79
- except:
80
- file_size = 0
81
-
82
- USE_STREAM = file_size > 30 * 1024 * 1024 # >30MB
83
-
84
- # Download content (streamed if large)
85
- content = b""
86
- hasher = hashlib.md5()
87
-
88
- with requests.get(url, stream=USE_STREAM) as resp:
89
- if resp.status_code != 200:
90
- raise HTTPException(400, "Could not download document")
91
-
92
- for chunk in resp.iter_content(chunk_size=8192):
93
- hasher.update(chunk)
94
- content += chunk
95
-
96
- # Cache key based on content hash
97
- content_hash = hasher.hexdigest()
98
- cache_file = os.path.join(CACHE_DIR, f"{content_hash}.pkl")
99
-
100
- # Return cached version if exists
101
- if os.path.exists(cache_file):
102
- print(f"✅ Loaded chunks from disk cache (key={content_hash})")
103
- with open(cache_file, "rb") as f:
104
- return pickle.load(f)
105
-
106
- # Determine content type
107
  content_type = resp.headers.get("Content-Type", "").lower()
108
  url_lower = url.lower()
109
- docs = []
110
 
111
  if "application/pdf" in content_type or ".pdf" in url_lower:
112
  with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
113
- tmp.write(content)
114
  tmp_path = tmp.name
115
  try:
116
  loader = PyMuPDFLoader(tmp_path)
@@ -118,9 +30,12 @@ def load_and_chunk(url: str) -> list[Document]:
118
  finally:
119
  os.remove(tmp_path)
120
 
121
- elif "application/vnd.openxmlformats-officedocument.wordprocessingml.document" in content_type or ".docx" in url_lower:
 
 
 
122
  with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp:
123
- tmp.write(content)
124
  tmp_path = tmp.name
125
  try:
126
  loader = Docx2txtLoader(tmp_path)
@@ -129,19 +44,12 @@ def load_and_chunk(url: str) -> list[Document]:
129
  os.remove(tmp_path)
130
 
131
  elif "text/plain" in content_type or ".txt" in url_lower:
132
- text = content.decode("utf-8", errors="ignore")
133
  docs = [Document(page_content=text)]
134
 
135
  else:
136
  raise HTTPException(400, f"Unsupported document type: {content_type}")
137
 
138
- # Split the docs
139
- splitter = SentenceTransformersTokenTextSplitter(model_name=MODEL_DIR, tokens_per_chunk=500, chunk_overlap=80)
140
- chunks = splitter.split_documents(docs)
141
-
142
- # Save to cache
143
- with open(cache_file, "wb") as f:
144
- pickle.dump(chunks, f)
145
- print(f"💾 Chunks cached to {cache_file}")
146
-
147
- return chunks
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  import tempfile
3
  import requests
 
 
4
 
5
  from fastapi import HTTPException
6
+ # from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader
7
  from langchain_community.document_loaders import PyMuPDFLoader, Docx2txtLoader
8
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
9
+ from langchain_text_splitters.sentence_transformers import SentenceTransformersTokenTextSplitter # give better results but slow can use later for project
10
  from langchain.schema import Document
 
11
 
12
  MODEL_DIR = os.path.join("/tmp", "e5-large-v2")
 
 
13
 
14
  def load_and_chunk(url: str) -> list[Document]:
15
+ print(url)
16
+ resp = requests.get(url)
17
+ if resp.status_code != 200:
18
+ raise HTTPException(400, "Could not download document")
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  content_type = resp.headers.get("Content-Type", "").lower()
21
  url_lower = url.lower()
 
22
 
23
  if "application/pdf" in content_type or ".pdf" in url_lower:
24
  with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
25
+ tmp.write(resp.content)
26
  tmp_path = tmp.name
27
  try:
28
  loader = PyMuPDFLoader(tmp_path)
 
30
  finally:
31
  os.remove(tmp_path)
32
 
33
+ elif (
34
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document" in content_type
35
+ or ".docx" in url_lower
36
+ ):
37
  with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp:
38
+ tmp.write(resp.content)
39
  tmp_path = tmp.name
40
  try:
41
  loader = Docx2txtLoader(tmp_path)
 
44
  os.remove(tmp_path)
45
 
46
  elif "text/plain" in content_type or ".txt" in url_lower:
47
+ text = resp.content.decode("utf-8", errors="ignore")
48
  docs = [Document(page_content=text)]
49
 
50
  else:
51
  raise HTTPException(400, f"Unsupported document type: {content_type}")
52
 
53
+ splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=120,separators=["\n\n", "\n", ".", " ", ""])
54
+ # splitter = SentenceTransformersTokenTextSplitter(model_name = MODEL_DIR,tokens_per_chunk=500, chunk_overlap=80)
55
+ return splitter.split_documents(docs)