bs01338's picture
Upload 20 files
b1ec669 verified
Raw
History Blame Contribute Delete
3.36 kB
"""Step 5 — Gradio chat UI for the Medical RAG Chatbot.
Run locally:
python app.py
Then open the printed local URL in your browser. This same file is the
entry point HuggingFace Spaces looks for, so it deploys with no changes.
"""
from __future__ import annotations
import gradio as gr
from src.rag_pipeline import RAGChatbot
DISCLAIMER = (
"⚠️ **Research demo only — not medical advice.** "
"Answers are generated from a small set of documents and may be incomplete "
"or wrong. Always consult a qualified ophthalmologist."
)
EXAMPLE_QUESTIONS = [
"What is diabetic retinopathy?",
"How is the severity of diabetic retinopathy graded?",
"What deep learning methods are used to detect diabetic retinopathy?",
"Why is early screening for diabetic retinopathy important?",
]
def ensure_vector_store() -> None:
"""Build the ChromaDB index on first run if it doesn't exist yet.
This makes the app self-contained on HuggingFace Spaces: if the vector
store is missing, it downloads the source PDFs (when needed) and ingests
them automatically, so the Space works without a manual build step.
"""
from src.config import CHROMA_DIR, DATA_DIR
if CHROMA_DIR.exists():
return # already built — nothing to do
print("No vector store found — building it now (first-run setup) ...")
# If there are no source PDFs yet, try to fetch the defaults.
if not list(DATA_DIR.glob("*.pdf")):
try:
from src.download_sources import main as download_main
download_main()
except Exception as exc: # noqa: BLE001
print(f" (could not auto-download sources: {exc})")
# Build the index from whatever PDFs are present.
from src.ingest import main as ingest_main
ingest_main()
# Load the pipeline once at startup. If something is missing (no docs or no key),
# show the error in the UI instead of crashing silently.
_load_error: str | None = None
bot: RAGChatbot | None = None
try:
ensure_vector_store()
bot = RAGChatbot()
except Exception as exc: # noqa: BLE001
_load_error = str(exc)
def _format_sources(sources) -> str:
if not sources:
return ""
seen = []
for d in sources:
src = d.metadata.get("source", "unknown")
page = d.metadata.get("page", "?")
label = f"{src} (p.{page})"
if label not in seen:
seen.append(label)
return "\n\n**Sources used:** " + "; ".join(seen)
def respond(message: str, history):
"""Gradio chat callback."""
if _load_error:
return f"⚠️ Setup incomplete: {_load_error}"
if not message.strip():
return "Please type a question about diabetic retinopathy."
resp = bot.ask(message)
return resp.answer + _format_sources(resp.sources)
with gr.Blocks(title="Medical RAG Chatbot") as demo:
gr.Markdown("# 🩺 Medical RAG Chatbot — Diabetic Retinopathy")
gr.Markdown(
"Ask questions about diabetic retinopathy. Answers are grounded in "
"open-access research papers using Retrieval-Augmented Generation "
"(LangChain · ChromaDB · sentence-transformers · Llama 3.3 70B on Groq)."
)
gr.Markdown(DISCLAIMER)
gr.ChatInterface(
fn=respond,
examples=EXAMPLE_QUESTIONS,
)
if __name__ == "__main__":
demo.launch()