CoolFace
Apppublic

AbdulHadiDev/PDF_Query_bot_using_Pinecone_and_Langchain

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py241 linesDownload Raw Back to root
1# import os2# import pinecone3# from langchain.document_loaders import PyPDFDirectoryLoader4# from langchain.text_splitter import RecursiveCharacterTextSplitter5# from langchain_google_genai import GoogleGenerativeAIEmbeddings6# from langchain_google_genai import ChatGoogleGenerativeAI7# from langchain.vectorstores import Pinecone8# from langchain.chains import RetrievalQA9# from dotenv import load_dotenv10# import streamlit as st11 12 13# load_dotenv()14 15 16# pinecone_client = pinecone.Pinecone(17#     api_key=os.getenv("PINECONE_API_KEY"),  18#     environment="us-east-1"  19# )20 21# index_name = "langchainvector"22 23# embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")24 25# def read_doc(directory):26#     file_loader = PyPDFDirectoryLoader(directory)27#     documents = file_loader.load()28#     return documents29 30 31# doc = read_doc('documents/')32# print(f"Loaded {len(doc)} documents")33 34 35# index=Pinecone.from_documents(doc,embeddings,index_name=index_name)36 37# llm = ChatGoogleGenerativeAI(model='gemini-1.5-pro', temperature=0.9)38 39# chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=index.as_retriever())40 41 42# def retrieve_answers(query):43#     response = chain.run(query)44#     return response45 46# # Streamlit app47# st.set_page_config(page_title="Budget Bot", page_icon=":robot_face:")48# st.header("Sindh Budget Quiz bot(PDF questioning bot using Pinecone and Langchain)")49 50# user_input = st.text_input("Input:", key="input")51# submit = st.button("Ask the question")52 53 54# if submit:55#     if not user_input:56#         st.warning("Please enter a question.")57#     else:58#         try:59#             answer = retrieve_answers(user_input)60#             st.subheader("The Response is")61#             st.write(answer)62#         except Exception as e:63#             st.error(f"An error occurred: {e}")64 65# Deployment on hugging face66 67import os68import time69import streamlit as st70import pinecone71from dotenv import load_dotenv72 73from langchain.document_loaders import PyPDFDirectoryLoader74from langchain.text_splitter import RecursiveCharacterTextSplitter75from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI76from langchain_community.vectorstores import Pinecone as PineconeVectorStore77from langchain.chains import RetrievalQA78 79 80# =========================81# Setup & Config82# =========================83 84load_dotenv()85 86st.set_page_config(87    page_title="Sindh Budget Quiz Bot (PDF Q&A with Pinecone + LangChain)",88    page_icon=":robot_face:",89)90st.title("Sindh Budget Quiz Bot")91 92PINECONE_API_KEY = os.getenv("PINECONE_API_KEY")93GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")94 95if not PINECONE_API_KEY or not GOOGLE_API_KEY:96    st.error("❌ Missing API keys. Set PINECONE_API_KEY and GOOGLE_API_KEY in your .env or Space Secrets.")97    st.stop()98 99# Your Pinecone index details (from your dashboard screenshot)100INDEX_NAME = "langchainvector"101PINECONE_ENV = "us-east-1"   # AWS us-east-1 (matches your console)102EMBED_DIM = 768              # Google "models/embedding-001" returns 768-d vectors103NAMESPACE = "__default__"    # leave default unless you need multi-tenant104 105 106# =========================107# Utilities108# =========================109 110@st.cache_data(show_spinner=False)111def load_documents(directory: str):112    """Load PDFs from a directory."""113    loader = PyPDFDirectoryLoader(directory)114    docs = loader.load()115    return docs116 117@st.cache_resource(show_spinner=False)118def build_embeddings():119    """Create (and cache) the embeddings model."""120    return GoogleGenerativeAIEmbeddings(121        model="models/embedding-001",122        api_key=GOOGLE_API_KEY123    )124 125def ensure_pinecone_ready():126    """Init Pinecone and ensure index exists (v2 client)."""127    try:128        pinecone.init(api_key=PINECONE_API_KEY, environment=PINECONE_ENV)129    except Exception as e:130        st.error(f"❌ Failed to initialize Pinecone: {e}\n"131                 f"- Make sure your Space can reach external services.\n"132                 f"- If on HF free CPU, networking to Pinecone can be blocked.")133        st.stop()134 135    # Create the index if it doesn't exist136    try:137        existing = pinecone.list_indexes()138        if INDEX_NAME not in existing:139            pinecone.create_index(140                name=INDEX_NAME,141                dimension=EMBED_DIM,142                metric="cosine"143            )144            # Wait briefly for serverless index to be ready145            time.sleep(5)146    except Exception as e:147        st.error(f"❌ Could not verify/create Pinecone index '{INDEX_NAME}': {e}")148        st.stop()149 150def get_index_stats():151    """Describe index stats (to avoid re-embedding if already populated)."""152    try:153        idx = pinecone.Index(INDEX_NAME)154        return idx.describe_index_stats()155    except Exception:156        return None157 158@st.cache_resource(show_spinner=False)159def make_vectorstore(docs):160    """Create or connect to the Pinecone vectorstore, embedding docs only if needed."""161    # Split docs before embedding162    splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)163    chunks = splitter.split_documents(docs)164 165    # Check if the index already has vectors; if it does, just connect without re-upserting166    stats = get_index_stats()167    has_vectors = False168    if stats and "namespaces" in stats and NAMESPACE in stats["namespaces"]:169        ns_stats = stats["namespaces"][NAMESPACE]170        has_vectors = ns_stats.get("vector_count", 0) > 0171 172    embeddings = build_embeddings()173 174    if has_vectors:175        # Just connect to existing index176        vs = PineconeVectorStore(177            index=pinecone.Index(INDEX_NAME),178            embedding=embeddings,179            text_key="text",180            namespace=NAMESPACE181        )182        return vs183 184    # Otherwise, (first run) embed & upsert185    vs = PineconeVectorStore.from_documents(186        documents=chunks,187        embedding=embeddings,188        index_name=INDEX_NAME,189        namespace=NAMESPACE190    )191    return vs192 193@st.cache_resource(show_spinner=False)194def make_chain(vectorstore):195    """Build the RetrievalQA chain once."""196    llm = ChatGoogleGenerativeAI(model="gemini-1.5-pro", temperature=0.2, api_key=GOOGLE_API_KEY)197    retriever = vectorstore.as_retriever(search_kwargs={"k": 4})198    chain = RetrievalQA.from_chain_type(199        llm=llm,200        chain_type="stuff",201        retriever=retriever202    )203    return chain204 205 206# =========================207# Pipeline Bootstrap208# =========================209 210st.caption("Loading documents from `documents/`…")211docs = load_documents("documents/")212st.success(f"✅ Loaded {len(docs)} PDF pages")213 214st.caption("Connecting to Pinecone…")215ensure_pinecone_ready()216 217st.caption("Preparing vector store…")218vectorstore = make_vectorstore(docs)219st.success("✅ Vector store ready")220 221chain = make_chain(vectorstore)222 223 224# =========================225# UI226# =========================227 228prompt = st.text_input("Ask a question about the Sindh Budget PDFs:")229if st.button("Ask"):230    if not prompt.strip():231        st.warning("Please enter a question.")232    else:233        with st.spinner("Thinking…"):234            try:235                answer = chain.run(prompt)236                st.subheader("Answer")237                st.write(answer)238            except Exception as e:239                st.error(f"❌ Error while answering: {e}")240 241