File size: 5,002 Bytes
b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 b29e221 e40fe64 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | import os
import streamlit as st
from rag_utility import process_document_to_chroma_db, answer_question
# Page configuration
st.set_page_config(
page_title="AI Doubt Teacher - RAG",
page_icon="π",
layout="wide"
)
# Set the working directory where PDFs will be stored
working_dir = "pdfs"
# Ensure directory exists
os.makedirs(working_dir, exist_ok=True)
# Initialize session state for tracking processed files
if "processed_files" not in st.session_state:
st.session_state.processed_files = set()
if "db_ready" not in st.session_state:
st.session_state.db_ready = False
st.title("π AI Doubt Teacher - Document RAG")
st.caption("Upload your textbooks/notes and ask doubts in natural language")
# Sidebar for document management
with st.sidebar:
st.header("π Document Manager")
# File uploader widget
uploaded_file = st.file_uploader(
"Upload a PDF file",
type=["pdf"],
accept_multiple_files=False
)
if uploaded_file is not None:
save_path = os.path.join(working_dir, uploaded_file.name)
# Check if file already processed
if uploaded_file.name in st.session_state.processed_files:
st.info(f"π '{uploaded_file.name}' is already processed.")
else:
# Save the file
try:
with open(save_path, "wb") as f:
f.write(uploaded_file.getbuffer())
st.success(f"β
File '{uploaded_file.name}' uploaded!")
# Process the document
with st.spinner("π Processing document... This may take a minute."):
try:
result = process_document_to_chroma_db(working_dir)
st.session_state.processed_files.add(uploaded_file.name)
st.session_state.db_ready = True
st.success("β
Document processed! Ready for Q&A.")
except Exception as e:
st.error(f"β οΈ Error: {e}")
except Exception as e:
st.error(f"β οΈ Error saving file: {e}")
# Show processed files
if st.session_state.processed_files:
st.divider()
st.subheader("π Processed Documents")
for file_name in st.session_state.processed_files:
st.markdown(f"- π {file_name}")
# Clear database button
if st.session_state.processed_files:
if st.button("ποΈ Clear All Documents", type="secondary"):
# Clear ChromaDB
import shutil
db_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "doc_vectorstore")
if os.path.exists(db_path):
shutil.rmtree(db_path)
# Clear uploaded files
for file_name in os.listdir(working_dir):
os.remove(os.path.join(working_dir, file_name))
st.session_state.processed_files.clear()
st.session_state.db_ready = False
st.rerun()
# Main Q&A area
st.divider()
st.subheader("π¬ Ask Your Doubt")
# Text input for user's question
user_question = st.text_area(
"Type your question about the uploaded documents:",
placeholder="e.g., What is Newton's First Law? Explain with examples.",
height=100
)
col1, col2, col3 = st.columns([1, 1, 3])
with col1:
ask_button = st.button("π Get Answer", type="primary", use_container_width=True)
with col2:
clear_button = st.button("ποΈ Clear Question", use_container_width=True)
if clear_button:
st.session_state.user_question = ""
st.rerun()
if ask_button:
if not st.session_state.db_ready:
st.warning("β οΈ Please upload and process a document first.")
elif not user_question.strip():
st.warning("β οΈ Please enter a question.")
else:
with st.spinner("π€ Thinking..."):
try:
answer = answer_question(user_question)
# Display answer in a nice card
st.markdown("### π€ AI Tutor's Answer")
st.markdown(
f"""
<div style="
background-color: #f0f2f6;
padding: 20px;
border-radius: 10px;
border-left: 5px solid #4CAF50;
margin-bottom: 20px;
">
{answer}
</div>
""",
unsafe_allow_html=True
)
# Option to save answer
if st.button("π Copy Answer"):
st.write("Answer copied to clipboard! (Use Ctrl+C)")
except Exception as e:
st.error(f"β οΈ Error generating answer: {e}")
# Footer
st.divider()
st.caption("Built with β€οΈ using Groq, DeepSeek-R1, and ChromaDB") |