aimprabu's picture
fix(ui): gracefully format dictionary error payloads to prevent TypeError
55a76a3
Raw History Blame Contribute Delete
1.88 kB
import httpx
from bs4 import BeautifulSoup
from app.core.exceptions import IngestionError
from app.core.logging import logger
from app.infrastructure.document_loader.base import DocumentLoaderBase
class UrlDocumentLoader(DocumentLoaderBase):
"""Loads document content by fetching a remote URL and extracting raw text."""
def load(self, source: str) -> str:
logger.info(f"Scraping document URL content: {source}...")
try:
# Fetch content with timeout
response = httpx.get(source, timeout=15.0, follow_redirects=True)
if response.status_code != 200:
logger.error(f"URL load failed with HTTP code {response.status_code} for URL: {source}")
raise IngestionError(f"HTTP request failed with status {response.status_code}")
soup = BeautifulSoup(response.text, "html.parser")
# Remove scripts and style elements to clean text
for script in soup(["script", "style", "header", "footer", "nav"]):
script.decompose()
text = soup.get_text(separator="\n")
# Simple whitespace cleanup
lines = (line.strip() for line in text.splitlines())
chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
text = "\n".join(chunk for chunk in chunks if chunk)
logger.info("URL content successfully fetched and cleaned.")
return text
except httpx.HTTPError as e:
logger.error(f"HTTP connection failed for URL {source}: {e}")
raise IngestionError(f"Network request failed for URL: {e}") from e
except Exception as e:
logger.error(f"Failed to scrape URL {source}: {e}")
raise IngestionError(f"URL parsing failed: {e}") from e