DEV Community

Venkatesh Jonnagadla
Venkatesh Jonnagadla

Posted on

Your First RAG Application for a PDF Summay


import os
import tempfile
from pathlib import Path

import streamlit as st
import httpx
from pdfminer.high_level import extract_text

from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_classic.chains import RetrievalQA



# Streamlit configuration

st.set_page_config(page_title="RAG PDF Summarizer")
st.title("RAG-powered PDF Summarizer")


# API configuration

API_KEY = "Your API Key"
BASE_URL = "https://yourbaseurl.com"

if not API_KEY:
    st.error("GENAI_API_KEY is not configured.")
    st.stop()

# Keep TLS certificate verification enabled.
client = httpx.Client(timeout=120.0, verify=True)

llm = ChatOpenAI(
    base_url=BASE_URL,
    model="azure_ai/genailab-maas-DeepSeek-V3-0324",
    api_key=API_KEY,
    http_client=client,
)

embedding_model = OpenAIEmbeddings(
    base_url=BASE_URL,
    model="azure/genailab-maas-text-embedding-3-large",
    api_key=API_KEY,
    http_client=client,
)


# PDF upload

uploaded_file = st.file_uploader(
    "Upload a PDF",
    type=["pdf"],
)

if uploaded_file is not None:
    temp_path = None

    try:
        # Step 1: Save the uploaded PDF temporarily
        with tempfile.NamedTemporaryFile(
            delete=False,
            suffix=".pdf",
        ) as temp_file:
            temp_file.write(uploaded_file.getvalue())
            temp_path = temp_file.name

        # Step 2: Extract text
        with st.spinner("Extracting PDF text..."):
            raw_text = extract_text(temp_path)

        if not raw_text or not raw_text.strip():
            st.error(
                "No readable text found. "
                "If this is a scanned PDF, OCR is required."
            )
            st.stop()

        # Step 3: Split text into chunks
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=1000,
            chunk_overlap=200,
        )

        chunks = text_splitter.split_text(raw_text)

        if not chunks:
            st.error("No text chunks were generated.")
            st.stop()

        st.write(f"Created {len(chunks)} text chunks.")

        # Step 4: Create the Chroma vector database
        chroma_dir = Path.home() / "rag_chroma_data"
        chroma_dir.mkdir(parents=True, exist_ok=True)

        with st.spinner("Indexing PDF..."):
            vectordb = Chroma.from_texts(
                texts=chunks,
                embedding=embedding_model,
                persist_directory=str(chroma_dir),
                collection_name="pdf_collection",
            )

        # Step 5: Create retriever
        retriever = vectordb.as_retriever(
            search_type="similarity",
            search_kwargs={"k": min(5, len(chunks))},
        )

        # Step 6: Create the RAG chain
        rag_chain = RetrievalQA.from_chain_type(
            llm=llm,
            chain_type="stuff",
            retriever=retriever,
            return_source_documents=True,
        )

        # Step 7: Generate the summary
        summary_prompt = (
            "Summarize the uploaded document using the retrieved context. "
            "Explain the main topics, key findings, important facts, "
            "and conclusions. Do not invent unsupported information."
        )

        with st.spinner("Generating summary..."):
            result = rag_chain.invoke({"query": summary_prompt})

        # Step 8: Display results
        st.subheader("Document Summary")
        st.write(result["result"])

        with st.expander("View source documents"):
            for i, doc in enumerate(
                result["source_documents"],
                start=1,
            ):
                st.markdown(f"**Source {i}**")
                st.write(doc.page_content)

    except Exception as exc:
        st.error(f"Processing failed: {exc}")

    finally:
        if temp_path and os.path.exists(temp_path):
            os.remove(temp_path)

Enter fullscreen mode Exit fullscreen mode

Top comments (0)