UmerAS commited on
Commit
9ef2666
Β·
verified Β·
1 Parent(s): 0dca4ae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -55
app.py CHANGED
@@ -1,20 +1,18 @@
1
  import streamlit as st
2
- from piper import PiperVoice
3
  import base64, tempfile, requests, os, re
4
- import whisper # local Whisper model
 
 
 
5
 
6
- # ────────────────────────────────────────────────────
7
  st.set_page_config(page_title="Med11 – AI Emergency Guide", page_icon="🩺")
8
 
9
- # Groq key (unchanged)
10
  GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
11
-
12
- # Session flags
13
  st.session_state.setdefault("show_numbers", False)
14
  st.session_state.setdefault("upload_id", 0)
15
  st.session_state.setdefault("chat_history", [])
16
 
17
- # ────────────────────────────────────────────────────
18
  @st.cache_resource(show_spinner="Loading Whisper model…")
19
  def _load_whisper():
20
  return whisper.load_model("base")
@@ -26,11 +24,7 @@ def groq_reply(prompt: str, model="llama3-8b-8192"):
26
  "messages": [
27
  {
28
  "role": "system",
29
- "content": (
30
- "You are an emergency-response medic. "
31
- "Classify the emergency, rate severity, and give clear, step-by-step first-aid. "
32
- "Limit to 120 words."
33
- ),
34
  },
35
  *st.session_state.chat_history,
36
  {"role": "user", "content": prompt},
@@ -40,7 +34,7 @@ def groq_reply(prompt: str, model="llama3-8b-8192"):
40
  }
41
  r = requests.post(
42
  url, json=payload,
43
- headers={"Authorization": f"Bearer {GROQ_API_KEY}"},
44
  timeout=45,
45
  )
46
  r.raise_for_status()
@@ -51,40 +45,34 @@ def transcribe_audio(file_path: str) -> str:
51
  result = model.transcribe(file_path)
52
  return result["text"]
53
 
54
- # ──────────────────────────────────────────
55
- # Markdown sanitization for TTS
56
- # ──────────────────────────────────────────
57
-
58
  def clean_text_for_tts(text: str) -> str:
59
- text = re.sub(r"\*\*|\*|__|_", "", text) # bold/italic
60
- text = re.sub(r"[|~>#]", "", text) # misc. MD
61
- text = re.sub(r"[\u2600-\u26FF\u2700-\u27BF]+", "", text) # emojis
62
- text = re.sub(r"\s+", " ", text) # whitespace
63
  return text.strip()
64
 
65
  def tts_player(text: str):
66
  clean_text = clean_text_for_tts(text)
 
 
 
67
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as fp:
68
- voice = PiperVoice.load("en_US-amy-low.onnx")
69
- voice.synthesize(clean_text, fp.name)
70
  audio_bytes = open(fp.name, "rb").read()
 
71
  b64 = base64.b64encode(audio_bytes).decode()
72
  st.components.v1.html(
73
  f"""
74
- <audio id=\"ttsAudio\" controls style=\"width:100%;\">
75
- <source src=\"data:audio/wav;base64,{b64}\" type=\"audio/wav\">
76
  </audio>
77
- <div style=\"margin-top:4px;\">
78
- <button onclick=\"document.getElementById('ttsAudio').playbackRate=1\">1Γ—</button>
79
- <button onclick=\"document.getElementById('ttsAudio').playbackRate=1.5\">1.5Γ—</button>
80
- <button onclick=\"document.getElementById('ttsAudio').playbackRate=2\">2Γ—</button>
81
- </div>
82
  """,
83
  height=90,
84
  )
85
  os.remove(fp.name)
86
 
87
- # ──────────────────────────────────────────
88
  st.title("🩺 Med11 – Upload Emergency Voice")
89
 
90
  if st.button("πŸ“ž Emergency Numbers"):
@@ -92,24 +80,17 @@ if st.button("πŸ“ž Emergency Numbers"):
92
 
93
  if st.session_state.show_numbers:
94
  with st.expander("Key Emergency Numbers (Pakistan)", expanded=True):
95
- st.markdown(
96
- """
97
  | Service | Number |
98
  |---------|--------|
99
  | πŸš‘ **Edhi Ambulance** | **115** |
100
  | πŸš’ **Rescue / Fire** | **1122** |
101
  | πŸš“ Police | **15** |
102
  | πŸ’Š Poison Control (NIH) | **051-9255075** |
103
- """
104
- )
105
 
106
- # Upload audio
107
  uploader_key = f"audio_{st.session_state.upload_id}"
108
- audio_file = st.file_uploader(
109
- "Upload a WAV/MP3 describing the emergency",
110
- type=["wav", "mp3", "m4a"],
111
- key=uploader_key,
112
- )
113
 
114
  if audio_file:
115
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp:
@@ -130,10 +111,7 @@ if audio_file:
130
  if transcript:
131
  with st.spinner("Analyzing…"):
132
  try:
133
- result = groq_reply(
134
- f'Analyze this emergency: "{transcript}". '
135
- "Classify type, rate severity, and give brief first-aid steps."
136
- )
137
  st.session_state.chat_history.append({"role": "user", "content": transcript})
138
  st.session_state.chat_history.append({"role": "assistant", "content": result})
139
  except Exception as e:
@@ -149,17 +127,10 @@ if audio_file:
149
  st.markdown("---")
150
  st.markdown("**Need to tell me more? Upload another voice clip below.**")
151
 
152
- # ──────────────────────────────────────────
153
  col1, col2 = st.columns(2)
154
  with col1:
155
  if st.button("πŸ₯ Nearest Hospital (Google Maps)"):
156
- st.markdown(
157
- "[Open Maps β†’](https://www.google.com/maps/search/hospital/)",
158
- unsafe_allow_html=True,
159
- )
160
  with col2:
161
- if st.button("πŸ—œοΈ Nearby Pharmacies"):
162
- st.markdown(
163
- "[Open Maps β†’](https://www.google.com/maps/search/pharmacy/)",
164
- unsafe_allow_html=True,
165
- )
 
1
  import streamlit as st
 
2
  import base64, tempfile, requests, os, re
3
+ import whisper
4
+ from piper import PiperVoice
5
+ import numpy as np
6
+ import soundfile as sf
7
 
8
+ # ─────────────────────────────────────────────────────────────
9
  st.set_page_config(page_title="Med11 – AI Emergency Guide", page_icon="🩺")
10
 
 
11
  GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
 
 
12
  st.session_state.setdefault("show_numbers", False)
13
  st.session_state.setdefault("upload_id", 0)
14
  st.session_state.setdefault("chat_history", [])
15
 
 
16
  @st.cache_resource(show_spinner="Loading Whisper model…")
17
  def _load_whisper():
18
  return whisper.load_model("base")
 
24
  "messages": [
25
  {
26
  "role": "system",
27
+ "content": "You are an emergency-response medic. Classify the emergency, rate severity, and give clear, step-by-step first-aid. Limit to 120 words.",
 
 
 
 
28
  },
29
  *st.session_state.chat_history,
30
  {"role": "user", "content": prompt},
 
34
  }
35
  r = requests.post(
36
  url, json=payload,
37
+ headers={"Authorization": f"Bearer {GROQ_API_KEY.strip()}"},
38
  timeout=45,
39
  )
40
  r.raise_for_status()
 
45
  result = model.transcribe(file_path)
46
  return result["text"]
47
 
 
 
 
 
48
  def clean_text_for_tts(text: str) -> str:
49
+ text = re.sub(r"\*\*|\*|__|_", "", text)
50
+ text = re.sub(r"[|~>#]", "", text)
51
+ text = re.sub(r"[\u2600-\u26FF\u2700-\u27BF]+", "", text)
52
+ text = re.sub(r"\s+", " ", text)
53
  return text.strip()
54
 
55
  def tts_player(text: str):
56
  clean_text = clean_text_for_tts(text)
57
+ voice = PiperVoice.load("models/en_US-amy-low.onnx")
58
+ samples = voice.synthesize(clean_text)
59
+
60
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as fp:
61
+ sf.write(fp.name, samples, voice.sample_rate)
 
62
  audio_bytes = open(fp.name, "rb").read()
63
+
64
  b64 = base64.b64encode(audio_bytes).decode()
65
  st.components.v1.html(
66
  f"""
67
+ <audio id="ttsAudio" controls style="width:100%;">
68
+ <source src="data:audio/wav;base64,{b64}" type="audio/wav">
69
  </audio>
 
 
 
 
 
70
  """,
71
  height=90,
72
  )
73
  os.remove(fp.name)
74
 
75
+ # ─────────────────────────────────────────────────────────────
76
  st.title("🩺 Med11 – Upload Emergency Voice")
77
 
78
  if st.button("πŸ“ž Emergency Numbers"):
 
80
 
81
  if st.session_state.show_numbers:
82
  with st.expander("Key Emergency Numbers (Pakistan)", expanded=True):
83
+ st.markdown("""
 
84
  | Service | Number |
85
  |---------|--------|
86
  | πŸš‘ **Edhi Ambulance** | **115** |
87
  | πŸš’ **Rescue / Fire** | **1122** |
88
  | πŸš“ Police | **15** |
89
  | πŸ’Š Poison Control (NIH) | **051-9255075** |
90
+ """)
 
91
 
 
92
  uploader_key = f"audio_{st.session_state.upload_id}"
93
+ audio_file = st.file_uploader("Upload a WAV/MP3 describing the emergency", type=["wav", "mp3", "m4a"], key=uploader_key)
 
 
 
 
94
 
95
  if audio_file:
96
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp:
 
111
  if transcript:
112
  with st.spinner("Analyzing…"):
113
  try:
114
+ result = groq_reply(f'Analyze this emergency: "{transcript}". Classify type, rate severity, and give brief first-aid steps.')
 
 
 
115
  st.session_state.chat_history.append({"role": "user", "content": transcript})
116
  st.session_state.chat_history.append({"role": "assistant", "content": result})
117
  except Exception as e:
 
127
  st.markdown("---")
128
  st.markdown("**Need to tell me more? Upload another voice clip below.**")
129
 
 
130
  col1, col2 = st.columns(2)
131
  with col1:
132
  if st.button("πŸ₯ Nearest Hospital (Google Maps)"):
133
+ st.markdown("[Open Maps β†’](https://www.google.com/maps/search/hospital/)", unsafe_allow_html=True)
 
 
 
134
  with col2:
135
+ if st.button("πŸ—ΊοΈ Nearby Pharmacies"):
136
+ st.markdown("[Open Maps β†’](https://www.google.com/maps/search/pharmacy/)", unsafe_allow_html=True)