Pontonkid commited on
Commit
d2d8662
·
verified ·
1 Parent(s): 9f8ae5f

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +80 -68
src/streamlit_app.py CHANGED
@@ -6,8 +6,9 @@ from PIL import Image
6
  from huggingface_hub import InferenceClient
7
 
8
  # -----------------------------------------------------------------------------
9
- # 0. AUTO-FIX FOR UPLOAD ERROR (RUNS FIRST)
10
  # -----------------------------------------------------------------------------
 
11
  config_dir = ".streamlit"
12
  if not os.path.exists(config_dir):
13
  os.makedirs(config_dir)
@@ -20,18 +21,16 @@ with open(os.path.join(config_dir, "config.toml"), "w") as f:
20
  st.set_page_config(page_title="SHINUI | Intelligent Care", page_icon="✨", layout="wide")
21
 
22
  # RETRIEVE API KEY
23
- # Make sure "HF_TOKEN" is in your Space Settings -> Secrets
24
  HF_TOKEN = os.environ.get("HF_TOKEN")
25
-
26
  if not HF_TOKEN:
27
  st.error("⚠️ API Key missing! Please add 'HF_TOKEN' in Space Settings > Secrets.")
28
  st.stop()
29
 
30
- # INITIALIZE CLIENT
31
  client = InferenceClient(token=HF_TOKEN)
32
 
33
  # -----------------------------------------------------------------------------
34
- # 2. STATE MANAGEMENT (LOGIN & HISTORY)
35
  # -----------------------------------------------------------------------------
36
  if 'page' not in st.session_state: st.session_state.page = 'landing'
37
  if 'logged_in' not in st.session_state: st.session_state.logged_in = False
@@ -40,59 +39,34 @@ if 'history' not in st.session_state: st.session_state.history = []
40
  if 'result' not in st.session_state: st.session_state.result = None
41
 
42
  # -----------------------------------------------------------------------------
43
- # 3. THE BRAIN (Llama 3.2 Logic)
44
  # -----------------------------------------------------------------------------
45
  def get_ai_insight(input_type, content):
46
  """
47
- Handles AI processing using Llama 3.2 Vision Instruct.
48
  """
49
- prompt_base = "You are SHINUI, a professional medical AI assistant. Analyze the following input and provide a concise risk assessment and next steps."
50
-
51
  try:
52
- # A. VISION (Llama 3.2 Vision)
53
  if input_type == "Image":
54
- messages = [
55
- {
56
- "role": "user",
57
- "content": [
58
- {"type": "image"},
59
- {"type": "text", "text": prompt_base}
60
- ]
61
- }
62
- ]
63
- # Pass image directly to the client
64
  response = client.chat_completion(
65
- model="meta-llama/Llama-3.2-11B-Vision-Instruct",
66
- messages=messages,
67
- max_tokens=500,
68
- image=content # The PIL Image object
69
  )
70
  return response.choices[0].message.content
71
 
72
- # B. AUDIO (Whisper -> Llama)
73
- elif input_type == "Audio":
74
- # 1. Transcribe
75
- transcription = client.automatic_speech_recognition(
76
- model="openai/whisper-large-v3-turbo",
77
- audio=content
78
- ).text
79
-
80
- # 2. Analyze Text
81
- messages = [{"role": "user", "content": f"{prompt_base} Patient speech: '{transcription}'"}]
82
- analysis = client.chat_completion(
83
- model="meta-llama/Llama-3.2-11B-Vision-Instruct",
84
- messages=messages,
85
- max_tokens=500
86
- )
87
- return f"**Transcript:** '{transcription}'\n\n**Analysis:** {analysis.choices[0].message.content}"
88
-
89
- # C. TEXT (Llama)
90
  elif input_type == "Text":
91
- messages = [{"role": "user", "content": f"{prompt_base} Patient notes: '{content}'"}]
92
  response = client.chat_completion(
93
- model="meta-llama/Llama-3.2-11B-Vision-Instruct",
94
- messages=messages,
95
- max_tokens=500
96
  )
97
  return response.choices[0].message.content
98
 
@@ -108,8 +82,7 @@ st.markdown("""
108
  .stApp {
109
  background-color: #020617;
110
  background-image: radial-gradient(circle at 50% 0%, #1e293b 0%, #020617 70%);
111
- font-family: 'Plus Jakarta Sans', sans-serif;
112
- color: #f8fafc;
113
  }
114
  .shinui-card {
115
  background: rgba(30, 41, 59, 0.4); border: 1px solid rgba(148, 163, 184, 0.1);
@@ -125,7 +98,7 @@ st.markdown("""
125
  """, unsafe_allow_html=True)
126
 
127
  # -----------------------------------------------------------------------------
128
- # 5. HELPER FUNCTIONS
129
  # -----------------------------------------------------------------------------
130
  def nav_to(page):
131
  st.session_state.page = page
@@ -155,21 +128,47 @@ def show_landing():
155
  Medical Intelligence.<br><span style='color:#38bdf8;'>Simplified.</span>
156
  </h1>
157
  <p style='font-size: 1.2rem; color: #94a3b8; margin-bottom: 40px;'>
158
- SHINUI uses Llama 3.2 Vision AI to analyze medical data instantly.
159
  </p>
160
  """, unsafe_allow_html=True)
161
  b1, b2 = st.columns([1, 2])
162
  with b1:
163
  if st.button("Sign In"): nav_to('login')
 
 
164
 
165
  with c2:
166
  st.markdown("""
167
  <div class='shinui-card'>
168
- <h3>🧬 Multimodal Brain</h3>
169
- <p style='color:#94a3b8;'>Powered by Meta Llama 3.2 Vision.</p>
170
  </div>
171
  """, unsafe_allow_html=True)
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  # --- LOGIN ---
174
  def show_login():
175
  c1, c2, c3 = st.columns([1,1,1])
@@ -187,11 +186,13 @@ def show_login():
187
 
188
  # --- DASHBOARD ---
189
  def show_dashboard():
190
- # SIDEBAR
191
  with st.sidebar:
192
  st.markdown(f"### 👤 {st.session_state.user_email}")
 
 
193
  st.markdown("---")
194
- st.write("HISTORY LOG")
195
  if st.session_state.history:
196
  for h in reversed(st.session_state.history):
197
  st.markdown(f"<div style='font-size:0.8rem; padding:5px; border-left:2px solid #38bdf8; margin-bottom:5px;'>{h[:50]}...</div>", unsafe_allow_html=True)
@@ -202,7 +203,7 @@ def show_dashboard():
202
 
203
  # MAIN UI
204
  st.title("Diagnostic Interface")
205
- t1, t2, t3 = st.tabs(["📷 Vision", "🎙️ Voice", "📝 Text"])
206
 
207
  # TAB 1: VISION
208
  with t1:
@@ -216,20 +217,8 @@ def show_dashboard():
216
  st.session_state.history.append(res)
217
  st.markdown("</div>", unsafe_allow_html=True)
218
 
219
- # TAB 2: VOICE
220
  with t2:
221
- st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
222
- audio_input = st.audio_input("Record Symptoms")
223
- if audio_input:
224
- if st.button("Analyze Recording"):
225
- with st.spinner("Transcribing & Analyzing..."):
226
- res = get_ai_insight("Audio", audio_input.read())
227
- st.session_state.result = res
228
- st.session_state.history.append(res)
229
- st.markdown("</div>", unsafe_allow_html=True)
230
-
231
- # TAB 3: TEXT
232
- with t3:
233
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
234
  txt = st.text_area("Clinical Notes")
235
  if txt and st.button("Analyze Notes"):
@@ -248,11 +237,34 @@ def show_dashboard():
248
  </div>
249
  """, unsafe_allow_html=True)
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  # -----------------------------------------------------------------------------
252
  # 7. ROUTER
253
  # -----------------------------------------------------------------------------
254
  if st.session_state.page == 'landing': show_landing()
 
255
  elif st.session_state.page == 'login': show_login()
256
  elif st.session_state.page == 'dashboard':
257
  if st.session_state.logged_in: show_dashboard()
 
 
 
258
  else: nav_to('login')
 
6
  from huggingface_hub import InferenceClient
7
 
8
  # -----------------------------------------------------------------------------
9
+ # 0. AUTO-FIX FOR UPLOAD ERROR (CRITICAL STEP)
10
  # -----------------------------------------------------------------------------
11
+ # This code runs instantly to create the config file needed for uploads.
12
  config_dir = ".streamlit"
13
  if not os.path.exists(config_dir):
14
  os.makedirs(config_dir)
 
21
  st.set_page_config(page_title="SHINUI | Intelligent Care", page_icon="✨", layout="wide")
22
 
23
  # RETRIEVE API KEY
 
24
  HF_TOKEN = os.environ.get("HF_TOKEN")
 
25
  if not HF_TOKEN:
26
  st.error("⚠️ API Key missing! Please add 'HF_TOKEN' in Space Settings > Secrets.")
27
  st.stop()
28
 
29
+ # INITIALIZE CLIENT (Ungated Models)
30
  client = InferenceClient(token=HF_TOKEN)
31
 
32
  # -----------------------------------------------------------------------------
33
+ # 2. STATE MANAGEMENT
34
  # -----------------------------------------------------------------------------
35
  if 'page' not in st.session_state: st.session_state.page = 'landing'
36
  if 'logged_in' not in st.session_state: st.session_state.logged_in = False
 
39
  if 'result' not in st.session_state: st.session_state.result = None
40
 
41
  # -----------------------------------------------------------------------------
42
+ # 3. THE BRAIN (Simplified Logic)
43
  # -----------------------------------------------------------------------------
44
  def get_ai_insight(input_type, content):
45
  """
46
+ Handles Text and Image processing using open-source models.
47
  """
 
 
48
  try:
49
+ # A. VISION (BLIP - Open Source)
50
  if input_type == "Image":
51
+ # 1. Describe image
52
+ desc = client.image_to_text(model="Salesforce/blip-image-captioning-large", image=content)
53
+
54
+ # 2. Analyze medically
55
+ prompt = f"I have a medical image showing: '{desc}'. Please analyze this medically for risks."
 
 
 
 
 
56
  response = client.chat_completion(
57
+ model="HuggingFaceH4/zephyr-7b-beta",
58
+ messages=[{"role": "user", "content": prompt}],
59
+ max_tokens=400
 
60
  )
61
  return response.choices[0].message.content
62
 
63
+ # B. TEXT (Zephyr - Open Source)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  elif input_type == "Text":
65
+ prompt = f"Analyze these symptoms medically: '{content}'"
66
  response = client.chat_completion(
67
+ model="HuggingFaceH4/zephyr-7b-beta",
68
+ messages=[{"role": "user", "content": prompt}],
69
+ max_tokens=400
70
  )
71
  return response.choices[0].message.content
72
 
 
82
  .stApp {
83
  background-color: #020617;
84
  background-image: radial-gradient(circle at 50% 0%, #1e293b 0%, #020617 70%);
85
+ font-family: 'Plus Jakarta Sans', sans-serif; color: #f8fafc;
 
86
  }
87
  .shinui-card {
88
  background: rgba(30, 41, 59, 0.4); border: 1px solid rgba(148, 163, 184, 0.1);
 
98
  """, unsafe_allow_html=True)
99
 
100
  # -----------------------------------------------------------------------------
101
+ # 5. NAVIGATION
102
  # -----------------------------------------------------------------------------
103
  def nav_to(page):
104
  st.session_state.page = page
 
128
  Medical Intelligence.<br><span style='color:#38bdf8;'>Simplified.</span>
129
  </h1>
130
  <p style='font-size: 1.2rem; color: #94a3b8; margin-bottom: 40px;'>
131
+ SHINUI analyzes medical data instantly using open AI.
132
  </p>
133
  """, unsafe_allow_html=True)
134
  b1, b2 = st.columns([1, 2])
135
  with b1:
136
  if st.button("Sign In"): nav_to('login')
137
+ with b2:
138
+ if st.button("About SHINUI"): nav_to('about')
139
 
140
  with c2:
141
  st.markdown("""
142
  <div class='shinui-card'>
143
+ <h3>🧬 Dual-Core Engine</h3>
144
+ <p style='color:#94a3b8;'>Text & Vision Analysis.</p>
145
  </div>
146
  """, unsafe_allow_html=True)
147
 
148
+ # --- ABOUT PAGE ---
149
+ def show_about():
150
+ if st.button("← Back Home"): nav_to('landing')
151
+ st.markdown("<br>", unsafe_allow_html=True)
152
+ st.markdown("""
153
+ <div class='shinui-card'>
154
+ <h2 style='color:#38bdf8'>About SHINUI</h2>
155
+ <p style='font-size:1.1rem; line-height:1.6'>
156
+ SHINUI is an AI-powered medical assistant designed to bring clarity to complex health data.
157
+ Whether it's a handwritten note, a lab result, or a pill bottle, SHINUI helps you understand it.
158
+ </p>
159
+ <hr style='border-color:#333'>
160
+ <h3>Our Mission</h3>
161
+ <p>To democratize access to medical understanding through simple, secure AI.</p>
162
+ <br>
163
+ <h3>How it Works</h3>
164
+ <ol>
165
+ <li><b>Upload:</b> Send an image or text description.</li>
166
+ <li><b>Process:</b> Our AI analyzes the visual and textual data.</li>
167
+ <li><b>Result:</b> Get a clear, jargon-free explanation.</li>
168
+ </ol>
169
+ </div>
170
+ """, unsafe_allow_html=True)
171
+
172
  # --- LOGIN ---
173
  def show_login():
174
  c1, c2, c3 = st.columns([1,1,1])
 
186
 
187
  # --- DASHBOARD ---
188
  def show_dashboard():
189
+ # SIDEBAR NAV
190
  with st.sidebar:
191
  st.markdown(f"### 👤 {st.session_state.user_email}")
192
+ if st.button("Home / Dashboard"): nav_to('dashboard')
193
+ if st.button("About"): nav_to('about_internal')
194
  st.markdown("---")
195
+ st.write("HISTORY")
196
  if st.session_state.history:
197
  for h in reversed(st.session_state.history):
198
  st.markdown(f"<div style='font-size:0.8rem; padding:5px; border-left:2px solid #38bdf8; margin-bottom:5px;'>{h[:50]}...</div>", unsafe_allow_html=True)
 
203
 
204
  # MAIN UI
205
  st.title("Diagnostic Interface")
206
+ t1, t2 = st.tabs(["📷 Image Scan", "📝 Text Analysis"])
207
 
208
  # TAB 1: VISION
209
  with t1:
 
217
  st.session_state.history.append(res)
218
  st.markdown("</div>", unsafe_allow_html=True)
219
 
220
+ # TAB 2: TEXT
221
  with t2:
 
 
 
 
 
 
 
 
 
 
 
 
222
  st.markdown("<div class='shinui-card'>", unsafe_allow_html=True)
223
  txt = st.text_area("Clinical Notes")
224
  if txt and st.button("Analyze Notes"):
 
237
  </div>
238
  """, unsafe_allow_html=True)
239
 
240
+ # --- INTERNAL ABOUT (For logged in users) ---
241
+ def show_about_internal():
242
+ with st.sidebar:
243
+ if st.button("← Back to Dashboard"): nav_to('dashboard')
244
+
245
+ st.markdown("""
246
+ <div class='shinui-card'>
247
+ <h2 style='color:#38bdf8'>System Information</h2>
248
+ <p>You are currently logged into the SHINUI Diagnostic System.</p>
249
+ <p>Version: 2.0.1 (Stable)</p>
250
+ <hr style='border-color:#333'>
251
+ <h3>Capabilities</h3>
252
+ <ul>
253
+ <li><b>Visual Analysis:</b> Uses Computer Vision to interpret X-rays, labels, and scans.</li>
254
+ <li><b>Text Processing:</b> Uses NLP to understand clinical notes and symptoms.</li>
255
+ </ul>
256
+ </div>
257
+ """, unsafe_allow_html=True)
258
+
259
  # -----------------------------------------------------------------------------
260
  # 7. ROUTER
261
  # -----------------------------------------------------------------------------
262
  if st.session_state.page == 'landing': show_landing()
263
+ elif st.session_state.page == 'about': show_about()
264
  elif st.session_state.page == 'login': show_login()
265
  elif st.session_state.page == 'dashboard':
266
  if st.session_state.logged_in: show_dashboard()
267
+ else: nav_to('login')
268
+ elif st.session_state.page == 'about_internal':
269
+ if st.session_state.logged_in: show_about_internal()
270
  else: nav_to('login')