medical_ai / app.py
panda992's picture
Update
ab1df2b
raw
history blame
4.81 kB
import gradio as gr
import requests
import os
import uuid
# --- Configuration ---
MODAL_BACKEND_URL = os.getenv("MODAL_BACKEND_URL", "").strip()
# --- UI Styling ---
CUSTOM_CSS = """
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
.gradio-container { max-width: 800px !important; margin: auto; padding-top: 2rem; }
#chatbot {
background-color: #F8F9FA;
border-radius: 0.5rem;
border: 1px solid #DEE2E6;
min-height: 450px;
}
.message {
padding: 1rem;
border-radius: 0.5rem;
}
.message.user {
background-color: #E9ECEF !important;
}
.message.bot {
background-color: #FFFFFF !important;
color: #343a40; /* Ensures text is visible on white background */
}
footer { display: none !important; }
"""
# --- Gradio UI Definition ---
with gr.Blocks(theme=gr.themes.Soft(), css=CUSTOM_CSS, title="MediAgent AI") as demo:
# --- State Management ---
conversation_state = gr.State(value={"history": []})
session_id = gr.State(lambda: str(uuid.uuid4()))
# --- Header ---
gr.Markdown("""
# 🧬 MediAgent AI (Conversational)
_Your Smart, Role-Aware AI Health Navigator_
""")
# --- User Role Selection ---
user_role = gr.Radio(
["patient", "doctor", "health_worker"],
label="πŸ‘€ Select Your Role",
value="patient",
info="The AI will adapt its communication style and questions based on your role."
)
# --- Chat Interface ---
chatbot = gr.Chatbot(
label="Conversation",
elem_id="chatbot",
bubble_full_width=False,
avatar_images=(None, "https://i.imgur.com/9k2p4t7.png")
)
with gr.Row():
user_textbox = gr.Textbox(
scale=4,
show_label=False,
placeholder="Type your message here...",
container=False,
)
submit_btn = gr.Button("Send", variant="primary", scale=1, min_width=150)
with gr.Row():
clear_btn = gr.ClearButton(
value="πŸ”„ Start New Conversation",
components=[chatbot, user_textbox, conversation_state]
)
# --- Main UI Logic ---
def handle_user_turn(
user_input: str,
chat_history: list,
user_role_selection: str,
current_state: dict,
sid: str
):
if not user_input.strip():
return {chatbot: chat_history, conversation_state: current_state}
chat_history.append((user_input, None))
yield {chatbot: chat_history}
if not MODAL_BACKEND_URL:
error_message = "### ❗ Configuration Error\n**Reason**: `MODAL_BACKEND_URL` environment variable is not set. The administrator needs to configure the application."
chat_history[-1] = (user_input, error_message)
yield {chatbot: chat_history}
return
headers = {"Content-Type": "application/json"}
payload = {
"user_input": user_input,
"session_id": sid,
"user_role": user_role_selection,
"conversation_state": current_state
}
try:
response = requests.post(MODAL_BACKEND_URL, headers=headers, json=payload, timeout=300)
response.raise_for_status()
backend_response = response.json()
bot_response_text = backend_response.get("response_text", "Sorry, I received an empty response.")
new_state = backend_response.get("conversation_state", current_state)
except requests.exceptions.RequestException as e:
bot_response_text = f"### ❗ Network Error\n**Reason**: Could not connect to the backend.\n**Details**: {str(e)}"
new_state = current_state
chat_history[-1] = (user_input, bot_response_text)
yield {chatbot: chat_history, conversation_state: new_state}
# --- Event Listeners ---
submit_event = submit_btn.click(
fn=handle_user_turn,
inputs=[user_textbox, chatbot, user_role, conversation_state, session_id],
outputs=[chatbot, conversation_state],
show_progress="hidden"
).then(lambda: gr.update(value=""), outputs=[user_textbox])
textbox_event = user_textbox.submit(
fn=handle_user_turn,
inputs=[user_textbox, chatbot, user_role, conversation_state, session_id],
outputs=[chatbot, conversation_state],
show_progress="hidden"
).then(lambda: gr.update(value=""), outputs=[user_textbox])
@clear_btn.click
def clear_chat():
return {"history": []}
if __name__ == "__main__":
print("Gradio App Starting...")
if not MODAL_BACKEND_URL:
print("\nWARNING: The `MODAL_BACKEND_URL` environment variable is not set.")
print("The application will run, but will show a configuration error.\n")
demo.queue()
demo.launch()