hassan773 commited on
Commit
1058fbd
·
verified ·
1 Parent(s): 0f2bfcb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -93
app.py CHANGED
@@ -11,51 +11,40 @@ import folium
11
  from streamlit_folium import st_folium
12
  from streamlit_geolocation import streamlit_geolocation
13
 
14
- # --- 1. CORE SYSTEM CONFIG ---
15
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
16
  if not GROQ_API_KEY:
17
- st.error("⚠️ API Key Missing! Please set it in your environment secrets.")
18
  st.stop()
19
 
20
- st.set_page_config(page_title="IntelliCare Portal | Hassan Naseer", layout="wide", page_icon="🏥")
21
 
22
- # --- 2. PREMIUM CSS ---
23
  st.markdown("""
24
  <style>
25
  [data-testid="stSidebar"] { background: #1e3a8a !important; }
26
  [data-testid="stSidebar"] * { color: #ffffff !important; }
27
- div.stButton > button {
28
- background-color: #1e3a8a !important; color: white !important;
29
- border: 1px solid #3b82f6 !important; transition: none !important;
30
- }
31
- .user-msg {
32
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
33
- color: white; padding: 15px; border-radius: 18px 18px 2px 18px;
34
- margin-bottom: 15px; margin-left: 20%; box-shadow: 0 4px 10px rgba(37, 99, 235, 0.2);
35
- }
36
- .ai-msg {
37
- background: #f1f5f9; color: #1e293b; padding: 15px; border-radius: 18px 18px 18px 2px;
38
- margin-bottom: 15px; margin-right: 20%; border: 1px solid #e2e8f0;
39
- }
40
  </style>
41
  """, unsafe_allow_html=True)
42
 
43
- # --- 3. DATA UTILS ---
44
  USER_DB, CALL_LOG_DB, CALL_SIGNAL_DB = "users_secure.csv", "call_history.csv", "active_calls.csv"
45
  def hash_pass(pwd): return hashlib.sha256(str.encode(pwd)).hexdigest()
46
  def load_db(file, cols):
47
  if os.path.exists(file): return pd.read_csv(file)
48
  return pd.DataFrame(columns=cols)
49
 
50
- # Session Setup
51
  if "logged_in" not in st.session_state: st.session_state.logged_in = False
52
  if "msgs" not in st.session_state: st.session_state.msgs = []
53
- if "active_doc" not in st.session_state: st.session_state.active_doc = None
54
  if "last_voice_hash" not in st.session_state: st.session_state.last_voice_hash = None
55
 
56
  # --- 4. AUTHENTICATION ---
57
  if not st.session_state.logged_in:
58
- st.markdown("<h1 style='text-align: center; color: #1e3a8a;'>🏥 IntelliCare Portal</h1>", unsafe_allow_html=True)
59
  c2 = st.columns([1, 2, 1])[1]
60
  with c2:
61
  t1, t2 = st.tabs(["🔐 Login", "📝 Register"])
@@ -76,57 +65,50 @@ if not st.session_state.logged_in:
76
  st.success("Registered!")
77
  st.stop()
78
 
79
- # --- 5. SIDEBAR & LANGUAGE ---
80
  with st.sidebar:
81
  st.markdown(f"### 👤 {st.session_state.username}")
82
- lang = st.radio("🌐 Language / زبان", ["English", "Urdu"])
83
- st.divider()
84
- if st.button("🗑️ Clear Chat" if lang == "English" else "🗑️ چیٹ صاف کریں"):
85
- st.session_state.msgs, st.session_state.active_doc = [], None
 
 
 
 
 
 
 
 
 
86
  st.rerun()
87
- if st.button("🚪 Logout"): st.session_state.logged_in = False; st.rerun()
88
  st.divider()
89
-
90
- # Translations
91
- chat_nav = "💬 AI Chat" if lang == "English" else "💬 اے آئی چیٹ"
92
- tools_nav = "🧪 Health Tools" if lang == "English" else "🧪 صحت کے اوزار"
93
- map_nav = "📍 Nearby Clinics" if lang == "English" else "📍 قریبی کلینک"
94
- call_nav = "📞 Video Consult" if lang == "English" else "📞 ویڈیو کال"
95
- hist_nav = "📜 Call History" if lang == "English" else "📜 کال ریکارڈ"
96
-
97
- nav = st.radio("Menu", [chat_nav, tools_nav, map_nav, call_nav, hist_nav]) if st.session_state.role == "Patient" else st.radio("Menu", ["🖥️ Desk", "📜 Logs"])
98
 
99
- # --- 6. AI CHAT (FIXED PDF REFERENCE & DOWNLOAD) ---
100
- if nav in [chat_nav, "💬 AI Chat", "💬 اے آئی چیٹ"]:
101
- st.markdown(f"### {chat_nav}")
102
-
103
- if st.session_state.active_doc:
104
- st.info("📂 Medical PDF Loaded. AI is analyzing your report." if lang == "English" else "📂 میڈیکل پی ڈی ایف لوڈ ہوگئی ہے۔ اے آئی تجزیہ کر رہا ہے۔")
105
- # PDF Summary Downloader
106
- st.download_button(
107
- label="📄 Download Analysis Summary" if lang == "English" else "📄 خلاصہ ڈاؤن لوڈ کریں",
108
- data=st.session_state.active_doc,
109
- file_name="clinical_summary.txt",
110
- mime="text/plain"
111
- )
112
 
 
 
 
 
 
 
 
 
 
113
  for m in st.session_state.msgs:
114
  st.markdown(f'<div class="{"user-msg" if m["role"] == "user" else "ai-msg"}">{m["content"]}</div>', unsafe_allow_html=True)
115
 
116
- cv, cp, cq = st.columns([0.6, 0.6, 8.8])
117
- with cv: v = st.audio_input("🎤", key=f"v_{len(st.session_state.msgs)}", label_visibility="collapsed")
118
- with cp:
119
- with st.popover(""):
120
- up = st.file_uploader("Upload PDF", type=['pdf'])
121
- if up:
122
- with pdfplumber.open(up) as f:
123
- st.session_state.active_doc = " ".join([p.extract_text() for p in f.pages if p.extract_text()])
124
- st.success("Extracted!" if lang == "English" else "ڈیٹا حاصل کر لیا گیا!")
125
- st.rerun()
126
- with cq: q = st.chat_input("Ask about your health..." if lang == "English" else "اپنی صحت کے بارے میں پوچھیں...")
127
 
128
  final_q = q if q else None
129
- if v and not final_q:
130
  vh = hashlib.md5(v.getvalue()).hexdigest()
131
  if vh != st.session_state.last_voice_hash:
132
  final_q = Groq(api_key=GROQ_API_KEY).audio.transcriptions.create(file=("a.wav", v.getvalue()), model="whisper-large-v3", response_format="text")
@@ -134,40 +116,18 @@ if nav in [chat_nav, "💬 AI Chat", "💬 اے آئی چیٹ"]:
134
 
135
  if final_q:
136
  st.session_state.msgs.append({"role": "user", "content": final_q})
137
- # Strict Medical Prompt with explicit PDF reference
138
- sys_p = f"You are the IntelliCare Medical Assistant. Language: {lang}. If PDF_CONTEXT is provided, explicitly state you are reading the user's report. Answer clinical queries only."
139
- ans = Groq(api_key=GROQ_API_KEY).chat.completions.create(model="llama-3.3-70b-versatile", messages=[{"role": "system", "content": sys_p}, {"role": "system", "content": f"PDF_CONTEXT: {st.session_state.active_doc}"}] + st.session_state.msgs)
140
  st.session_state.msgs.append({"role": "assistant", "content": ans.choices[0].message.content})
141
  st.rerun()
142
 
143
- # --- 7. ADDITIONAL TOOLS (MAPS, TOOLS, CALLS) ---
144
- elif nav in [tools_nav, "🧪 Health Tools", "🧪 صحت کے اوزار"]:
145
- st.markdown(f"### {tools_nav}")
146
- t = st.selectbox("Tool", ["⚖️ BMI Analyzer", "🩸 Glucose Tracker"])
147
- if t == "⚖️ BMI Analyzer":
148
- w, h = st.number_input("Weight (kg)", 70), st.number_input("Height (cm)", 175)
149
- bmi = round(w / ((h/100)**2), 1)
150
- st.metric("BMI", bmi)
151
- st.plotly_chart(go.Figure(go.Indicator(mode="gauge+number", value=bmi, gauge={'bar': {'color': "#3b82f6"}})))
152
-
153
- elif nav in [map_nav, "📍 Nearby Clinics", "📍 قریبی کلینک"]:
154
- st.markdown(f"### {map_nav}")
155
  loc = streamlit_geolocation()
156
  if loc.get("latitude"):
157
- m = folium.Map(location=[loc["latitude"], loc["longitude"]], zoom_start=14)
158
- folium.Marker([loc["latitude"], loc["longitude"]], popup="You").add_to(m)
159
- st_folium(m, width=1000, height=500)
160
-
161
- elif nav in [call_nav, "📞 Video Consult", "📞 ویڈیو کال"]:
162
- st.markdown(f"### {call_nav}")
163
- db = load_db(USER_DB, ["username", "role"])
164
- docs = db[db['role'] == 'Doctor']['username'].tolist()
165
- sel_doc = st.selectbox("Select Specialist", docs)
166
- if st.button("Request Call"):
167
- room = f"IntelliCare-{st.session_state.username}-{sel_doc}"
168
- log_entry = pd.DataFrame([{"Time": datetime.now().strftime("%Y-%m-%d %H:%M"), "Caller": st.session_state.username, "Receiver": sel_doc, "RoomID": room}])
169
- pd.concat([load_db(CALL_LOG_DB, ["Time", "Caller", "Receiver", "RoomID"]), log_entry]).to_csv(CALL_LOG_DB, index=False)
170
- pd.DataFrame([{"Caller": st.session_state.username, "Receiver": sel_doc, "RoomID": room, "Status": "Active"}]).to_csv(CALL_SIGNAL_DB, index=False)
171
- st.session_state.p_room = room
172
- if "p_room" in st.session_state:
173
- st.components.v1.html(f'<iframe src="https://meet.jit.si/{st.session_state.p_room}" width="100%" height="600px"></iframe>', height=650)
 
11
  from streamlit_folium import st_folium
12
  from streamlit_geolocation import streamlit_geolocation
13
 
14
+ # --- 1. SYSTEM CONFIG ---
15
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
16
  if not GROQ_API_KEY:
17
+ st.error("⚠️ API Key Missing!")
18
  st.stop()
19
 
20
+ st.set_page_config(page_title="IntelliCare | Hassan Naseer", layout="wide", page_icon="🏥")
21
 
22
+ # --- 2. CSS ---
23
  st.markdown("""
24
  <style>
25
  [data-testid="stSidebar"] { background: #1e3a8a !important; }
26
  [data-testid="stSidebar"] * { color: #ffffff !important; }
27
+ div.stButton > button { background-color: #1e3a8a !important; color: white !important; }
28
+ .user-msg { background: #3b82f6; color: white; padding: 12px; border-radius: 15px 15px 2px 15px; margin-bottom: 10px; margin-left: 25%; }
29
+ .ai-msg { background: #f1f5f9; color: #1e293b; padding: 12px; border-radius: 15px 15px 15px 2px; margin-bottom: 10px; margin-right: 25%; border: 1px solid #e2e8f0; }
 
 
 
 
 
 
 
 
 
 
30
  </style>
31
  """, unsafe_allow_html=True)
32
 
33
+ # --- 3. CORE LOGIC ---
34
  USER_DB, CALL_LOG_DB, CALL_SIGNAL_DB = "users_secure.csv", "call_history.csv", "active_calls.csv"
35
  def hash_pass(pwd): return hashlib.sha256(str.encode(pwd)).hexdigest()
36
  def load_db(file, cols):
37
  if os.path.exists(file): return pd.read_csv(file)
38
  return pd.DataFrame(columns=cols)
39
 
 
40
  if "logged_in" not in st.session_state: st.session_state.logged_in = False
41
  if "msgs" not in st.session_state: st.session_state.msgs = []
42
+ if "active_doc" not in st.session_state: st.session_state.active_doc = ""
43
  if "last_voice_hash" not in st.session_state: st.session_state.last_voice_hash = None
44
 
45
  # --- 4. AUTHENTICATION ---
46
  if not st.session_state.logged_in:
47
+ st.markdown("<h1 style='text-align: center;'>🏥 IntelliCare Portal</h1>", unsafe_allow_html=True)
48
  c2 = st.columns([1, 2, 1])[1]
49
  with c2:
50
  t1, t2 = st.tabs(["🔐 Login", "📝 Register"])
 
65
  st.success("Registered!")
66
  st.stop()
67
 
68
+ # --- 5. SIDEBAR ---
69
  with st.sidebar:
70
  st.markdown(f"### 👤 {st.session_state.username}")
71
+ lang = st.radio("🌐 Language", ["English", "Urdu"])
72
+
73
+ # PERMANENT DOWNLOAD BUTTON
74
+ chat_history_text = "\n".join([f"{m['role'].upper()}: {m['content']}" for m in st.session_state.msgs])
75
+ st.download_button(
76
+ label="📥 Download Full Chat PDF/Text",
77
+ data=chat_history_text,
78
+ file_name=f"IntelliCare_Chat_{datetime.now().strftime('%Y%m%d')}.txt",
79
+ mime="text/plain"
80
+ )
81
+
82
+ if st.button("🗑️ Clear Chat"):
83
+ st.session_state.msgs, st.session_state.active_doc = [], ""
84
  st.rerun()
 
85
  st.divider()
86
+ nav = st.radio("Menu", ["💬 Chat", "🧪 Lab", "📍 Maps", "📞 Video"]) if st.session_state.role == "Patient" else st.radio("Menu", ["🖥️ Desk", "📜 Logs"])
 
 
 
 
 
 
 
 
87
 
88
+ # --- 6. CHAT MODULE (FIXED INPUT BAR & PDF TEXT) ---
89
+ if nav == "💬 Chat":
90
+ st.markdown("### 💬 Clinical Intelligence Assistant")
 
 
 
 
 
 
 
 
 
 
91
 
92
+ # 1. Permanent PDF Reader UI
93
+ with st.expander("📄 Upload Medical PDF / Prescription"):
94
+ up = st.file_uploader("Drop PDF here", type=['pdf'], label_visibility="collapsed")
95
+ if up:
96
+ with pdfplumber.open(up) as f:
97
+ st.session_state.active_doc = " ".join([p.extract_text() for p in f.pages if p.extract_text()])
98
+ st.success("✅ Prescription/Report Analyzed!")
99
+
100
+ # 2. Display Chat
101
  for m in st.session_state.msgs:
102
  st.markdown(f'<div class="{"user-msg" if m["role"] == "user" else "ai-msg"}">{m["content"]}</div>', unsafe_allow_html=True)
103
 
104
+ # 3. FIXED INPUT BAR (Always visible)
105
+ st.divider()
106
+ c_v, c_q = st.columns([1, 9])
107
+ with c_v: v = st.audio_input("🎤", key="permanent_mic", label_visibility="collapsed")
108
+ with c_q: q = st.chat_input("Ask about your report or prescription...")
 
 
 
 
 
 
109
 
110
  final_q = q if q else None
111
+ if v and not final_q: # Voice-to-Text Logic
112
  vh = hashlib.md5(v.getvalue()).hexdigest()
113
  if vh != st.session_state.last_voice_hash:
114
  final_q = Groq(api_key=GROQ_API_KEY).audio.transcriptions.create(file=("a.wav", v.getvalue()), model="whisper-large-v3", response_format="text")
 
116
 
117
  if final_q:
118
  st.session_state.msgs.append({"role": "user", "content": final_q})
119
+ # AI Logic: PDF Text + Voice/Text
120
+ sys_p = f"Medical Assistant. Language: {lang}. If PDF exists, read and explain it like a human doctor. Focus on prescriptions and reports."
121
+ ans = Groq(api_key=GROQ_API_KEY).chat.completions.create(model="llama-3.3-70b-versatile", messages=[{"role": "system", "content": sys_p}, {"role": "system", "content": f"PDF_CONTENT: {st.session_state.active_doc}"}] + st.session_state.msgs)
122
  st.session_state.msgs.append({"role": "assistant", "content": ans.choices[0].message.content})
123
  st.rerun()
124
 
125
+ # --- 7. OTHER FEATURES ---
126
+ elif nav == "🧪 Lab":
127
+ st.plotly_chart(go.Figure(go.Indicator(mode="gauge+number", value=22, title={'text': "BMI Gauge"})))
128
+ elif nav == "📍 Maps":
 
 
 
 
 
 
 
 
129
  loc = streamlit_geolocation()
130
  if loc.get("latitude"):
131
+ st_folium(folium.Map(location=[loc["latitude"], loc["longitude"]], zoom_start=14), width=1000)
132
+ elif nav == "📞 Video":
133
+ st.write("Specialist Call Section")