Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| import requests | |
| # ============================================ | |
| # CONFIG | |
| # ============================================ | |
| API_URL = "http://127.0.0.1:8000" # FastAPI backend এর ঠিকানা | |
| st.set_page_config( | |
| page_title="Smart Doc QA", | |
| page_icon="📄", | |
| layout="centered", | |
| ) | |
| # ============================================ | |
| # SESSION STATE (Streamlit এর "memory") | |
| # ============================================ | |
| # Streamlit প্রতি interaction এ পুরো script আবার চালায়। | |
| # তাই messages আর upload status মনে রাখতে session_state লাগে। | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = [] | |
| if "doc_uploaded" not in st.session_state: | |
| st.session_state.doc_uploaded = False | |
| # ============================================ | |
| # HEADER | |
| # ============================================ | |
| st.title("📄 Smart Doc QA") | |
| st.caption("Upload a PDF and ask questions — answers grounded in your document.") | |
| # ============================================ | |
| # SIDEBAR — PDF Upload | |
| # ============================================ | |
| with st.sidebar: | |
| st.header("📤 Upload Document") | |
| uploaded_file = st.file_uploader("Choose a PDF", type=["pdf"]) | |
| if uploaded_file is not None: | |
| if st.button("Process Document", use_container_width=True): | |
| with st.spinner("Indexing document... ⏳"): | |
| # FastAPI /upload কে call করি | |
| files = {"file": (uploaded_file.name, uploaded_file.getvalue(), "application/pdf")} | |
| try: | |
| response = requests.post(f"{API_URL}/upload", files=files) | |
| if response.status_code == 200: | |
| data = response.json() | |
| st.session_state.doc_uploaded = True | |
| st.session_state.messages = [] # নতুন doc = নতুন chat | |
| st.success(f"✅ Indexed: {data['pages']} pages, {data['chunks']} chunks") | |
| else: | |
| st.error("Upload failed. Is the backend running?") | |
| except requests.exceptions.ConnectionError: | |
| st.error("⚠️ Cannot reach backend. Run: uvicorn app:app --reload") | |
| st.divider() | |
| # Example questions — user কে guide করে | |
| st.subheader("💡 Example Questions") | |
| st.markdown( | |
| "- What skills does the candidate have?\n" | |
| "- How many years of experience?\n" | |
| "- Is he suitable for an ML role?" | |
| ) | |
| st.divider() | |
| # Clear chat button | |
| if st.button("🗑️ Clear Chat", use_container_width=True): | |
| st.session_state.messages = [] | |
| st.rerun() | |
| # ============================================ | |
| # CHAT DISPLAY — আগের সব message দেখাও | |
| # ============================================ | |
| for msg in st.session_state.messages: | |
| with st.chat_message(msg["role"]): | |
| st.markdown(msg["content"]) | |
| # ============================================ | |
| # CHAT INPUT — user প্রশ্ন করে | |
| # ============================================ | |
| if prompt := st.chat_input("Ask a question about your document..."): | |
| if not st.session_state.doc_uploaded: | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| with st.chat_message("user"): | |
| st.markdown(prompt) | |
| with st.chat_message("assistant"): | |
| guide_msg = ( | |
| "👋 I'd love to help! But first, please upload a PDF " | |
| "from the sidebar and click **Process Document**. " | |
| "Once it's indexed, I can answer questions about it." | |
| ) | |
| st.markdown(guide_msg) | |
| st.session_state.messages.append( | |
| {"role": "assistant", "content": guide_msg} | |
| ) | |
| else: | |
| # User এর message দেখাও ও সংরক্ষণ করো | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| with st.chat_message("user"): | |
| st.markdown(prompt) | |
| # Backend কে জিজ্ঞেস করো | |
| with st.chat_message("assistant"): | |
| with st.spinner("Thinking... 🤔"): | |
| try: | |
| response = requests.post( | |
| f"{API_URL}/ask", | |
| json={"question": prompt}, | |
| ) | |
| if response.status_code == 200: | |
| data = response.json() | |
| answer = data["answer"] | |
| sources = data.get("sources_used", 0) | |
| st.markdown(answer) | |
| st.caption(f"📎 Answer based on {sources} document section(s)") | |
| # | |
| st.session_state.messages.append( | |
| {"role": "assistant", "content": answer} | |
| ) | |
| else: | |
| st.error("Failed to get an answer.") | |
| except requests.exceptions.ConnectionError: | |
| st.error("⚠️ Cannot reach backend. Is it running?") |