# app.py
import streamlit as st
from rag_engine import (
load_user_document,
build_retriever_from_docs,
answer_question
)
import os
# Set environment variables
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
os.environ["USER_AGENT"] = "PythonicAI/1.0 (+adinafraz01@gmail.com)"
st.set_page_config(
page_title="AI Documentation Assistant",
layout="wide",
initial_sidebar_state="expanded"
)
# -------------------- SESSION STATE --------------------
if "retriever" not in st.session_state:
st.session_state.retriever = None
if "docs_loaded" not in st.session_state:
st.session_state.docs_loaded = False
if "current_url" not in st.session_state:
st.session_state.current_url = None
if "processing" not in st.session_state:
st.session_state.processing = False
# -------------------- CUSTOM CSS --------------------
st.markdown("""
""", unsafe_allow_html=True)
# -------------------- SIDEBAR --------------------
with st.sidebar:
st.markdown("""
', unsafe_allow_html=True)
# Header
st.markdown("""
""", unsafe_allow_html=True)
# URL Input Section
st.markdown('
', unsafe_allow_html=True)
st.markdown("### 🌐 Enter Documentation URL")
# Initialize session state for URL if not exists
if "url_input" not in st.session_state:
st.session_state.url_input = "https://numpy.org/doc/2.3/user/absolute_beginners.html"
url = st.text_input(
"Enter the URL of Python documentation:",
value=st.session_state.url_input,
placeholder="https://example.com/python-docs",
label_visibility="collapsed",
key="url_input_field"
)
col1, col2 = st.columns([1, 1])
with col1:
load_clicked = st.button(
"📥 Load Document",
use_container_width=True,
type="primary",
disabled=not url.strip()
)
with col2:
if st.session_state.docs_loaded:
if st.button("🔄 Reload", use_container_width=True):
load_clicked = True
st.markdown('
', unsafe_allow_html=True)
# Handle document loading
if load_clicked:
if not url.strip():
st.error("❌ Please enter a valid URL")
else:
try:
with st.spinner("🔍 Loading and processing documentation..."):
# Store current URL
st.session_state.current_url = url
# Show progress
progress_text = st.empty()
progress_bar = st.progress(0)
progress_text.text("Downloading document...")
docs = load_user_document(url)
progress_bar.progress(30)
progress_text.text("Processing content...")
st.session_state.retriever = build_retriever_from_docs(docs)
progress_bar.progress(70)
progress_text.text("Finalizing...")
st.session_state.docs_loaded = True
progress_bar.progress(100)
progress_text.text("✅ Ready!")
st.success(f"✅ Successfully loaded documentation from: {url}")
# Show document info
st.markdown(f"""
📄 Loaded Document: {url}
📊 Pages Processed: {len(docs)}
✅ Status: Ready for questions
""", unsafe_allow_html=True)
except Exception as e:
st.error(f"❌ Error loading document: {str(e)}")
# Question Input Section (only show if document is loaded)
if st.session_state.docs_loaded:
st.markdown('
', unsafe_allow_html=True)
st.markdown("### 💭 Ask a Question")
# Example questions
st.markdown("**💡 Try asking:**")
col1, col2, col3, col4 = st.columns(4)
example_questions = [
"What is this library about?",
"How to get started?",
"What are the main functions?",
"Give me a code example"
]
for i, question in enumerate(example_questions):
col = [col1, col2, col3, col4][i]
with col:
if st.button(question, use_container_width=True):
st.session_state.question_input = question
st.rerun()
# Question input
question = st.text_area(
"Enter your Python-related question:",
value=st.session_state.get("question_input", ""),
placeholder="Example: What is NumPy? How to create arrays? What are the main functions?",
height=120,
key="question_input_area"
)
# Answer button
col1, col2, col3 = st.columns([2, 1, 1])
with col2:
if st.button("🚀 Get Answer", type="primary", use_container_width=True):
if not question.strip():
st.warning("Please enter a question")
else:
st.session_state.processing = True
st.session_state.current_question = question
with col3:
if st.button("🗑️ Clear", use_container_width=True):
st.session_state.question_input = ""
st.rerun()
st.markdown('
', unsafe_allow_html=True)
# Process and display answer
if st.session_state.get("processing") and st.session_state.get("current_question"):
with st.spinner("🤔 Analyzing document and generating answer..."):
try:
answer = answer_question(
st.session_state.current_question,
st.session_state.retriever
)
st.markdown("### 📝 Answer")
st.markdown(f'
{answer}
', unsafe_allow_html=True)
# Reset processing state
st.session_state.processing = False
except Exception as e:
st.error(f"❌ Error generating answer: {str(e)}")
st.session_state.processing = False
# Quick actions
st.markdown("""
💡 Tip: Ask specific questions for better answers. Try asking about functions, usage examples, or concepts.
""", unsafe_allow_html=True)
else:
# Welcome message when no document is loaded
st.markdown("""
👋 Welcome to AI Documentation Assistant!
Get started by entering a URL to Python documentation above.
Try the default URL or enter your own documentation link.
✨ Features:
- 📚 URL-based - Just paste a documentation URL
- 🤖 AI-powered - Get intelligent answers from docs
- ⚡ Fast processing - Quick document analysis
- 💬 Interactive - Ask follow-up questions
- 🎯 Python-focused - Optimized for Python documentation
🚀 Quick Start:
- Enter a Python documentation URL (or use the default)
- Click "Load Document"
- Wait a few seconds for processing
- Ask any Python-related question about the documentation
""", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)