ilaa-chenjeri-15's picture
Initial commit: Explainable RAG system
2db7cb0
Raw
History Blame Contribute Delete
5.17 kB
import sys
import os
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
import requests
from bs4 import BeautifulSoup
import json
import time
from tqdm import tqdm
from clean import clean_text
PROJECT_ROOT = Path(__file__).resolve().parents[2]
DOCS_OUTPUT = PROJECT_ROOT / "data" / "docs.json"
URLS = [
"https://huggingface.co/docs/transformers/index/",
"https://huggingface.co/docs/transformers/installation/",
"https://huggingface.co/docs/transformers/quicktour/",
"https://huggingface.co/docs/transformers/weightconverter",
"https://huggingface.co/docs/transformers/models",
"https://huggingface.co/docs/transformers/custom_models",
"https://huggingface.co/docs/transformers/monkey_patching",
"https://huggingface.co/docs/transformers/fusion_mapping",
"https://huggingface.co/docs/transformers/how_to_hack_models",
"https://huggingface.co/docs/transformers/model_sharing",
"https://huggingface.co/docs/transformers/serialization"
]
def normalize_code_block(code: str) -> str:
lines = code.split("\n")
stripped = [l.rstrip() for l in lines]
# Drop leading/trailing blank lines
while stripped and not stripped[0]:
stripped.pop(0)
while stripped and not stripped[-1]:
stripped.pop()
if not stripped:
return ""
def fix_python_spacing(s: str) -> str:
import re
s = re.sub(r'\s*\(\s*', '(', s)
s = re.sub(r'\s*\)\s*', ')', s)
s = re.sub(r'\s*\[\s*', '[', s)
s = re.sub(r'\s*\]\s*', ']', s)
s = re.sub(r'\s*,\s*', ', ', s)
s = re.sub(r'\s*:\s*', ': ', s)
s = re.sub(r'\s*=\s*', '=', s)
s = re.sub(r'([^=!<>])=([^=])', r'\1 = \2', s)
s = re.sub(r'==', ' == ', s)
s = re.sub(r'!=', ' != ', s)
s = re.sub(r' +', ' ', s)
return s.strip()
if len(stripped) <= 4 and all(len(l.split()) <= 4 for l in stripped if l):
joined = " ".join(l for l in stripped if l)
return joined
fixed = []
for line in stripped:
fixed.append(fix_python_spacing(line))
return "\n".join(fixed)
def extract_main_text(soup):
main = soup.find("main")
if not main:
return ""
for tag in main.find_all(["nav", "footer", "aside", "script", "style"]):
tag.decompose()
for tag in main.find_all(True):
if tag.get_text(" ", strip=True).startswith("and get access to the augmented"):
tag.decompose()
break
texts = []
for tag in main.find_all(["h1", "h2", "h3", "p", "li", "pre"]):
if tag.name == "pre":
code_tag = tag.find("code")
raw = (code_tag or tag).get_text("\n")
lang = ""
cls = (code_tag or tag).get("class", [])
for c in cls:
if c.startswith("language-"):
lang = c.replace("language-", "")
break
normalized = normalize_code_block(raw)
if not normalized or len(normalized.strip()) < 3:
continue
texts.append(f"\n```{lang}\n{normalized}\n```\n")
continue
content = tag.get_text(" ", strip=True)
if len(content) < 30:
continue
if tag.name in ["h1", "h2", "h3"]:
texts.append(f"\n{content}\n")
elif tag.name == "li":
texts.append(f"- {content}")
else:
texts.append(content)
return "\n\n".join(texts)
def process_url(url, retries=3):
headers = {"User-Agent": "Mozilla/5.0 (compatible; RAG-doc-fetcher/1.0)"}
for attempt in range(retries):
try:
response = requests.get(url, timeout=10, headers=headers)
response.raise_for_status()
print(f"[SUCCESS] Fetched: {url} (Attempt {attempt+1})\n")
soup = BeautifulSoup(response.text, "html.parser")
text = extract_main_text(soup)
cleaned = clean_text(text)
title = soup.title.string if soup.title else "No Title"
return {
"text": cleaned,
"metadata": {
"source": "huggingface",
"url": url,
"title": title
}
}
except requests.RequestException as e:
print(f"[Attempt {attempt+1}/{retries}] Failed: {url}")
print(f"Error: {e}")
if attempt < retries - 1:
print("Waiting 5 seconds before retry...\n")
time.sleep(5)
else:
print(f"[FAILED] All retries failed for: {url}\n")
return None
def main():
docs = []
for i, url in enumerate(tqdm(URLS, desc="Processing URLs")):
doc = process_url(url)
if doc and doc["text"].strip():
docs.append(doc)
if i < len(URLS) - 1:
time.sleep(0.75)
DOCS_OUTPUT.parent.mkdir(parents=True, exist_ok=True)
with open(DOCS_OUTPUT, "w") as f:
json.dump(docs, f, indent=2)
print(f"Saved {len(docs)} docs to {DOCS_OUTPUT}")
if __name__ == "__main__":
main()