File size: 4,383 Bytes
3987ef0
978c4cf
3987ef0
 
 
 
 
 
517de74
 
 
 
 
978c4cf
42d374e
 
 
517de74
42d374e
517de74
42d374e
 
 
 
 
 
 
 
 
978c4cf
3987ef0
 
 
978c4cf
3987ef0
 
 
978c4cf
42d374e
 
3987ef0
517de74
978c4cf
517de74
42d374e
 
517de74
 
 
 
42d374e
 
517de74
 
42d374e
517de74
42d374e
 
 
 
 
 
 
 
 
517de74
42d374e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3987ef0
978c4cf
42d374e
3987ef0
42d374e
 
3987ef0
42d374e
517de74
42d374e
 
 
 
 
 
 
 
 
 
 
 
978c4cf
3987ef0
 
 
 
 
 
 
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
# app.py

import os
import streamlit as st
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from mcp.orchestrator import orchestrate_search, answer_ai_question
from mcp.schemas import UnifiedSearchInput, UnifiedSearchResult
from pathlib import Path
import asyncio

ROOT_DIR = Path(__file__).resolve().parent
LOGO_PATH = ROOT_DIR / "assets" / "logo.png"

# --- FASTAPI BACKEND ---

api = FastAPI(
    title="MedGenesis MCP Server",
    version="2.0.0",
    description="MedGenesis AI unifies PubMed, ArXiv, OpenFDA, UMLS, and GPT-4o into a single biomedical intelligence platform."
)

api.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@api.post("/unified_search", response_model=UnifiedSearchResult)
async def unified_search_endpoint(data: UnifiedSearchInput):
    return await orchestrate_search(data.query)

@api.post("/ask_ai")
async def ask_ai_endpoint(question: str, context: str = ""):
    return await answer_ai_question(question, context)

# --- STREAMLIT UI ---

def render_ui():
    st.set_page_config(page_title="MedGenesis AI", layout="wide")

    # Header with logo and branding
    col1, col2 = st.columns([0.15, 0.85])
    with col1:
        if LOGO_PATH.exists():
            st.image(str(LOGO_PATH), width=100)
        else:
            st.markdown("🧬")
    with col2:
        st.markdown("""
            ## 🧬 **MedGenesis AI** – Biomedical Research Reimagined  
            *Unified Intelligence from PubMed, ArXiv, OpenFDA, UMLS, and GPT-4o*
        """)
        st.caption("Created by Oluwafemi Idiakhoa | Hugging Face Spaces")

    st.markdown("---")

    # Unified Semantic Search
    st.subheader("πŸ” Unified Semantic Search")
    query = st.text_input("Enter your biomedical research question:", placeholder="e.g. New treatments for glioblastoma using CRISPR")

    if st.button("Run Search πŸš€"):
        with st.spinner("Thinking... Gathering and analyzing data across 5 systems..."):
            results = asyncio.run(orchestrate_search(query))
            st.success("Search complete! πŸŽ‰")

            # Papers
            st.markdown("### πŸ“š Most Relevant Papers")
            for i, paper in enumerate(results["papers"], 1):
                st.markdown(f"**{i}. [{paper['title']}]({paper['link']})**  \n*{paper['authors']}* ({paper['source']})")
                st.markdown(f"<div style='font-size: 0.9em; color: gray'>{paper['summary']}</div>", unsafe_allow_html=True)

            # UMLS Concepts
            st.markdown("### 🧠 Biomedical Concept Enrichment (UMLS)")
            for concept in results["umls"]:
                if concept["cui"]:
                    st.markdown(f"πŸ”Ή **{concept['name']}** (CUI: `{concept['cui']}`): {concept['definition'] or 'No definition available'}")

            # Drug Safety
            st.markdown("### πŸ’Š Drug Safety Insights (OpenFDA)")
            for drug_report in results["drug_safety"]:
                if drug_report:
                    st.json(drug_report)

            # AI Summary
            st.markdown("### πŸ€– AI-Powered Summary")
            st.info(results["ai_summary"])

            # Suggested Reading
            st.markdown("### πŸ“– Suggested Links")
            for link in results["suggested_reading"]:
                st.write(f"- {link}")

    # Follow-up AI Q&A
    st.markdown("---")
    st.subheader("πŸ’¬ Ask AI a Follow-up Question")
    follow_up = st.text_input("What do you want to ask based on the above?", placeholder="e.g. What's the most promising therapy?")
    if st.button("Ask AI"):
        with st.spinner("Analyzing and responding..."):
            ai_answer = asyncio.run(answer_ai_question(follow_up, context=query))
            st.success("AI's Response:")
            st.write(ai_answer["answer"])

    # Footer
    st.markdown("---")
    st.markdown(
        "<div style='text-align: center; font-size: 0.9em;'>"
        "✨ Built with ❀️ by <strong>Oluwafemi Idiakhoa</strong> β€’ Powered by FastAPI, Streamlit, Hugging Face, OpenAI, UMLS, OpenFDA, and NCBI</div>",
        unsafe_allow_html=True
    )

# --- MAIN ENTRY ---

if __name__ == "__main__":
    import sys
    if "runserver" in sys.argv:
        import uvicorn
        uvicorn.run(api, host="0.0.0.0", port=7860)
    else:
        render_ui()