Developer0232/EHR_chatbot
0
1 2 3 4import streamlit as st5from main import invokeChatbot6from time import sleep7import os8import json9from PIL import Image10 11 12PRIMARY_COLOR = "#30D4B3"13SECONDARY_COLOR = "#2B4C7E" 14SESSION_FILE = "chat_history.json"15 16 17st.set_page_config(18 page_title="Medical Chatbot",19 page_icon="🏥",20 layout="centered"21)22 23 24st.markdown(f"""25<style>26 /* Overall page styling */27 .stApp {{28 background: linear-gradient(135deg, #000428, #004e92); /* Dark gradient background */29 color: white;30 font-family: 'Arial', sans-serif;31 }}32 33 /* Main container styling */34 .main .block-container {{35 padding: 2rem;36 max-width: 800px;37 background: rgba(0, 0, 0, 0.6); /* Semi-transparent black */38 backdrop-filter: blur(10px); /* Glass morphism effect */39 border-radius: 20px;40 border: 1px solid rgba(255, 255, 255, 0.1);41 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);42 margin-top: 20px;43 }}44 45 /* Header styling */46 .header {{47 display: flex;48 align-items: center;49 margin-bottom: 25px;50 background: rgba(0, 0, 0, 0.4);51 padding: 15px;52 border-radius: 15px;53 backdrop-filter: blur(5px);54 border: 1px solid rgba(255, 255, 255, 0.1);55 }}56 57 .logo-container {{58 background: linear-gradient(135deg, {PRIMARY_COLOR}, {SECONDARY_COLOR});59 width: 50px;60 height: 50px;61 border-radius: 12px;62 display: flex;63 align-items: center;64 justify-content: center;65 margin-right: 15px;66 box-shadow: 0 0 20px {PRIMARY_COLOR};67 }}68 69 .title {{70 color: {PRIMARY_COLOR};71 font-size: 32px;72 font-weight: 700;73 margin: 0;74 text-shadow: 0 0 10px {PRIMARY_COLOR};75 }}76 77 /* Chat container styling */78 .chat-container {{79 background: rgba(0, 0, 0, 0.4);80 border-radius: 15px;81 padding: 20px;82 margin: 20px 0;83 backdrop-filter: blur(5px);84 border: 1px solid rgba(255, 255, 255, 0.1);85 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);86 max-height: 500px;87 overflow-y: auto;88 position: relative;89 }}90 91 /* Loading spinner styling */92 .loading-spinner {{93 position: absolute;94 bottom: 20px;95 left: 50%;96 transform: translateX(-50%);97 display: flex;98 justify-content: center;99 align-items: center;100 background: rgba(0, 0, 0, 0.6);101 padding: 10px;102 border-radius: 8px;103 backdrop-filter: blur(5px);104 }}105 106 .loading-spinner::after {{107 content: "";108 width: 20px;109 height: 20px;110 border: 3px solid {PRIMARY_COLOR};111 border-top: 3px solid transparent;112 border-radius: 50%;113 animation: spin 1s linear infinite;114 box-shadow: 0 0 10px {PRIMARY_COLOR};115 }}116 117 @keyframes spin {{118 0% {{ transform: rotate(0deg); }}119 100% {{ transform: rotate(360deg); }}120 }}121 122 /* Message styling */123 .user-message {{124 background: rgba(255, 255, 255, 0.1);125 color: white;126 padding: 12px 18px;127 border-radius: 18px 18px 0 18px;128 margin: 10px 0;129 max-width: 80%;130 align-self: flex-end;131 margin-left: auto;132 box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);133 font-size: 16px;134 line-height: 1.5;135 font-weight: 400;136 backdrop-filter: blur(5px);137 }}138 139 .ai-message {{140 background: linear-gradient(135deg, {PRIMARY_COLOR}, {SECONDARY_COLOR});141 color: white;142 padding: 12px 18px;143 border-radius: 18px 18px 18px 0;144 margin: 10px 0;145 max-width: 80%;146 box-shadow: 0 0 20px {PRIMARY_COLOR};147 font-size: 16px;148 line-height: 1.5;149 font-weight: 400;150 }}151 152 /* Input area styling */153 .input-container {{154 background: rgb(245, 240, 240);155 padding: 15px;156 border-radius: 15px;157 backdrop-filter: blur(5px);158 border: 1px solid rgba(255, 255, 255, 0.1);159 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);160 margin-top: 20px;161 }}162 163 .stTextInput > div > div > input {{164 background: rgba(16, 241, 185, 0.37);165 color: white;166 font-size: 16px;167 border: 2px solid rgba(26, 3, 3, 0);168 border-radius: 8px;169 padding: 12px 15px;170 height: 50px;171 box-shadow: none !important;172 backdrop-filter: blur(5px);173 }}174 175 .stTextInput > div > div > input:focus {{176 border-color: {PRIMARY_COLOR};177 box-shadow: 0 0 10px {PRIMARY_COLOR} !important;178 }}179 180 /* Button styling */181 .stButton > button {{182 background: linear-gradient(135deg, {PRIMARY_COLOR}, {SECONDARY_COLOR});183 color: white;184 font-weight: 600;185 border: none;186 border-radius: 8px;187 padding: 10px 20px;188 height: 45px;189 transition: all 0.3s ease;190 box-shadow: 0 0 20px {PRIMARY_COLOR};191 }}192 193 /* NEON SEND BUTTON STYLING */194 .send-button > button {{195 background: rgba(16, 226, 241, 0.99);196 color: #000;197 font-weight: 600;198 border: 2px solid #0ff;199 border-radius: 8px;200 padding: 10px 20px;201 height: 45px;202 position: relative;203 overflow: hidden;204 text-transform: uppercase;205 letter-spacing: 2px;206 box-shadow: 0 0 25px #0ff;207 text-shadow: 0 0 5px #0ff, 0 0 10px #0ff;208 transition: all 0.3s ease;209 }}210 211 .send-button > button:hover {{212 background: rgba(16, 226, 241, 0.99); !important;213 color: white !important;214 box-shadow: 0 0 40px #0ff;215 text-shadow: none;216 }}217 218 .send-button > button::before {{219 background: rgba(16, 226, 241, 0.99);220 content: "";221 position: absolute;222 top: 0;223 left: -100%;224 width: 100%;225 height: 100%;226 background: rgba(255, 255, 255, 0.1);227 transition: 0.5s;228 animation: neon-scan 3s infinite;229 }}230 231 .b {{232 background: rgba(16, 226, 241, 0.99);233 }}234 235 @keyframes neon-scan {{236 0% {{ left: -100%; }}237 50% {{ left: 100%; }}238 100% {{ left: 100%; }}239 }}240 241 .clear-button > button {{242 background: rgba(255, 255, 255, 0.1);243 color: #CCCCCC;244 border: 1px solid rgba(255, 255, 255, 0.2);245 }}246 247 /* Footer styling */248 .footer {{249 background: rgba(0, 0, 0, 0.4);250 padding: 15px;251 border-radius: 15px;252 margin-top: 20px;253 text-align: center;254 font-size: 14px;255 color: #CCCCCC;256 backdrop-filter: blur(5px);257 border: 1px solid rgba(255, 255, 255, 0.1);258 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);259 }}260 /* Hide Streamlit branding */261 #MainMenu, footer, header {{262 visibility: hidden;263 }}264 265 /* Text styling for subtitle */266 .subtitle {{267 color: #CCCCCC;268 font-size: 16px;269 margin-top: -10px;270 margin-bottom: 25px;271 text-shadow: 0 0 10px {PRIMARY_COLOR};272 }}273</style>274""", unsafe_allow_html=True)275 276 277def load_chat_history():278 if os.path.exists(SESSION_FILE):279 with open(SESSION_FILE, "r") as f:280 return json.load(f)281 return [{"role": "ai", "content": "Hello! I'm here to assist you with your medical queries. How can I help you today?"}]282 283# Save chat history to file284def save_chat_history(messages):285 with open(SESSION_FILE, "w") as f:286 json.dump(messages, f)287 288# Initialize session state289if "messages" not in st.session_state:290 st.session_state.messages = load_chat_history()291 292if "submitted" not in st.session_state:293 st.session_state.submitted = False294 295# Display header with logo296col1, col2, col3 = st.columns([1, 5, 1])297with col2:298 try:299 image = Image.open("MRC-white-tm (1).png")300 resized_image = image.resize((500, 100))301 st.markdown(302 "<div style='display: flex; justify-content: center;'>",303 unsafe_allow_html=True,304 )305 st.image(resized_image)306 st.markdown("</div>", unsafe_allow_html=True)307 except FileNotFoundError:308 st.markdown(309 """310 <div style="display: flex; justify-content: center; align-items: center;">311 <div style="background-color: #30D4B3; width: 100px; height: 100px; border-radius: 10px; display: flex; align-items: center; justify-content: center;">312 <span style="color: white; font-size: 50px;">🏥</span>313 </div>314 </div>315 """,316 unsafe_allow_html=True,317 )318 319# Display title and subtitle320st.markdown(321 """322 <h1 style="text-align: center; color: #30D4B3; font-size: 20px; font-weight: 800; margin-top: 0px;">323 Medical Chatbot324 </h1>325 """,326 unsafe_allow_html=True,327)328st.markdown(329 """330 <p style="text-align: center; font-size: 20px; color: #CCCCCC; margin-top: -10px;">331 Your trusted AI assistant for medical information and guidance332 </p>333 """,334 unsafe_allow_html=True,335)336st.markdown(337 "<hr style='border: 2px solid #30D4B3; border-radius: 5px; margin-top: -5px;'>",338 unsafe_allow_html=True,339)340 341# Display chat history342for message in st.session_state.messages:343 role_class = "user-message" if message["role"] == "user" else "ai-message"344 st.markdown(f'<div class="{role_class}">{message["content"]}</div>', unsafe_allow_html=True)345 346# Handle user input submission347def handle_submit():348 if st.session_state.user_input and st.session_state.user_input.strip():349 st.session_state.submitted = True350 st.session_state.current_input = st.session_state.user_input351 352# Custom CSS for submit button353st.markdown(354 """355 <style>356 div[data-testid="stForm"] button {357 display: flex;358 justify-content: center;359 align-items: center;360 background-color: #007bff;361 color: white;362 border: none;363 padding: 8px 16px;364 border-radius: 5px;365 cursor: pointer;366 font-size: 16px;367 width: 100%;368 text-align: center;369 }370 div[data-testid="stForm"] button:hover {371 background-color: #0056b3;372 }373 </style>374 """,375 unsafe_allow_html=True,376)377 378# Chat input form379with st.form(key="chat_form", clear_on_submit=True):380 st.text_input("", placeholder="Type your medical question here...", key="user_input")381 submit_button = st.form_submit_button("Send", on_click=handle_submit)382 383# Clear chat button with unique key384clear_button = st.button("Clear Chat", key="clear_chat_button")385 386# Process user input387if st.session_state.get("submitted"):388 user_message = st.session_state.current_input389 st.session_state.messages.append({"role": "user", "content": user_message})390 391 with st.spinner("Thinking..."):392 response = invokeChatbot(user_message) # Replace with invokeChatbot(user_message)393 394 st.session_state.messages.append({"role": "ai", "content": response})395 save_chat_history(st.session_state.messages)396 st.session_state.submitted = False397 st.rerun()398 399# Handle chat clearing400if clear_button:401 st.session_state.messages = [{"role": "ai", "content": "Hello! I'm here to assist you with your medical queries. How can I help you today?"}]402 save_chat_history(st.session_state.messages)403 st.rerun()404 405# Footer notice406st.markdown(407 """408 <div class="footer">409 <p><strong>Important:</strong> This chatbot provides general information only and is not a substitute for professional medical advice.</p>410 <p>Always consult with a qualified healthcare provider for personal medical concerns.</p>411 </div>412 """,413 unsafe_allow_html=True,414)