3. main.py
This script is no longer needed
This script is to use streamlit, which was needed before docling
Streamlit App: RAG Helper – Breakdown
Streamlit-based front-end for querying a PDF using Docling, SentenceTransformers, and Ollama.
1. Page Configuration and Title
st.set_page_config(page_title="RAG Helper", layout="centered")
st.title(" RAG Helper: PDF Q&A with SentenceTransformers + Ollama")
- Sets Streamlit layout and app title.
2. File Upload Section
uploaded_file = st.file_uploader(" Upload a PDF file", type=["pdf"])
- Accepts a
.pdf
file from the user.
3. Temporary File Handling
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
tmp.write(uploaded_file.read())
pdf_path = Path(tmp.name)
- Writes the uploaded file to a temporary location for processing.
4. PDF Chunking with Docling
loader = DoclingLoader(file_path=[str(pdf_path)], export_type=ExportType.DOC_CHUNKS)
docs = loader.load()
chunks = [doc.page_content for doc in docs]
- Parses the PDF using
DoclingLoader
. - Extracts clean, semantic document chunks.
5. Embedding Chunks Locally
chunk_embeddings = embed_chunks(chunks)
- Uses a local SentenceTransformer model to convert text chunks to vector embeddings.
6. User Input: Question
question = st.text_input("💬 Ask a question about this document:")
- Provides a text input field for user queries.
7. Query Execution and Retrieval
top_chunks = search_similar_chunks(question, chunk_embeddings, chunks, top_k=3)
context = "\n\n".join(top_chunks)
prompt = f"Context:\n{context}\n\nQuestion: {question}\nAnswer:"
answer = query_ollama(prompt)
- Retrieves top-k similar chunks based on vector similarity.
- Formats context and question into a prompt for Ollama.
8. Display Answer and Chunks
st.subheader("🧾 Answer")
st.markdown(answer)
st.subheader("📌 Top Chunks Used")
- Displays Ollama's answer and the document chunks that were used.
9. Error Handling
except Exception as e:
st.error(f"❌ An error occurred: {e}")
- Shows a user-friendly error if anything goes wrong during upload, chunking, or querying.
import streamlit as st
from pathlib import Path
import tempfile
from langchain_docling.loader import DoclingLoader, ExportType
from local_embed import embed_chunks, search_similar_chunks
from api import query_ollama
st.set_page_config(page_title="RAG Helper", layout="centered")
st.title("🧠 RAG Helper: PDF Q&A with SentenceTransformers + Ollama")
# --- File Upload ---
uploaded_file = st.file_uploader("📄 Upload a PDF file", type=["pdf"])
if uploaded_file:
try:
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
tmp.write(uploaded_file.read())
pdf_path = Path(tmp.name)
# Step 1: Chunk the PDF using Docling
loader = DoclingLoader(file_path=[str(pdf_path)], export_type=ExportType.DOC_CHUNKS)
docs = loader.load()
chunks = [doc.page_content for doc in docs]
# Step 2: Embed all chunks using local model
st.info("🔍 Embedding chunks...")
chunk_embeddings = embed_chunks(chunks)
# Step 3: Ask a question
question = st.text_input("💬 Ask a question about this document:")
if st.button("🚀 Query Document"):
with st.spinner("Thinking..."):
top_chunks = search_similar_chunks(question, chunk_embeddings, chunks, top_k=3)
context = "\n\n".join(top_chunks)
prompt = f"Context:\n{context}\n\nQuestion: {question}\nAnswer:"
answer = query_ollama(prompt)
st.subheader("🧾 Answer")
st.markdown(answer)
st.subheader("📌 Top Chunks Used")
for i, chunk in enumerate(top_chunks, 1):
st.markdown(f"**Chunk {i}:**")
st.code(chunk[:500] + "..." if len(chunk) > 500 else chunk)
except Exception as e:
st.error(f"❌ An error occurred: {e}")