File size: 8,673 Bytes
410fd66 a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 68390a5 432d77e 68390a5 a6dea81 d2ad93f a6dea81 68390a5 410fd66 a6dea81 d2ad93f a6dea81 dd19451 d2ad93f 432d77e dd19451 a6dea81 432d77e dd19451 432d77e dd19451 d2ad93f dd19451 a6dea81 dd19451 a6dea81 d2ad93f a6dea81 432d77e a6dea81 dd19451 a6dea81 432d77e dd19451 432d77e dd19451 d2ad93f dd19451 a6dea81 dd19451 410fd66 432d77e a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 a6dea81 410fd66 68390a5 a6dea81 410fd66 a6dea81 410fd66 68390a5 a6dea81 68390a5 410fd66 a937006 432d77e a937006 410fd66 d2ad93f 410fd66 a6dea81 410fd66 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
import gradio as gr
import requests
import librosa
import numpy as np
import os
import hashlib
from datetime import datetime
from simple_salesforce import Salesforce
# Salesforce credentials (store securely in environment variables)
SF_USERNAME = os.getenv("SF_USERNAME", "[email protected]")
SF_PASSWORD = os.getenv("SF_PASSWORD", "voicebot1")
SF_SECURITY_TOKEN = os.getenv("SF_SECURITY_TOKEN", "jq4VVHUFti6TmzJDjjegv2h6b")
SF_INSTANCE_URL = os.getenv("SF_INSTANCE_URL", "https://voicebot-dev-ed.my.salesforce.com") # Verify correct API URL
# Hugging Face Inference API token (store in environment variables)
HF_TOKEN = os.getenv("HF_TOKEN") # No default; must be set in Space secrets
# Initialize Salesforce connection
try:
sf = Salesforce(
username=SF_USERNAME,
password=SF_PASSWORD,
security_token=SF_SECURITY_TOKEN,
instance_url=SF_INSTANCE_URL
)
except Exception as e:
print(f"Failed to connect to Salesforce: {str(e)}")
sf = None
# Hugging Face API endpoints
WHISPER_API_URL = "https://api-inference.huggingface.co/models/openai/whisper-tiny.en"
SYMPTOM_API_URL = "https://api-inference.huggingface.co/models/abhirajeshbhai/symptom-2-disease-net"
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
def compute_file_hash(file_path):
"""Compute MD5 hash of a file to check uniqueness."""
hash_md5 = hashlib.md5()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def transcribe_audio(audio_file):
"""Transcribe audio using Whisper API."""
if not HF_TOKEN:
error_msg = (
"Error transcribing audio: HF_TOKEN not set. Please set HF_TOKEN in Space secrets at "
"https://huggingface.co/spaces/your-username/HealthVoiceAnalyzer/settings."
)
print(error_msg)
return error_msg
try:
with open(audio_file, "rb") as f:
data = f.read()
response = requests.post(WHISPER_API_URL, headers=HEADERS, data=data)
response.raise_for_status()
result = response.json()
print(f"Whisper API response: {result}")
transcription = result.get("text", "").strip()
if not transcription:
return "Transcription empty. Please provide clear audio describing symptoms in English."
print(f"Transcription: {transcription}")
return transcription
except requests.exceptions.HTTPError as e:
error_msg = f"Error transcribing audio: {str(e)}"
if e.response.status_code == 401:
error_msg = (
"Error transcribing audio: Unauthorized. Please check HF_TOKEN in Space secrets at "
"https://huggingface.co/spaces/your-username/HealthVoiceAnalyzer/settings. "
"Ensure token has Inference API access (get at https://huggingface.co/settings/tokens)."
)
print(f"Whisper API error: {error_msg}, Status: {e.response.status_code}")
return error_msg
except Exception as e:
error_msg = f"Error transcribing audio: {str(e)}"
print(error_msg)
return error_msg
def analyze_symptoms(text):
"""Analyze symptoms using Symptom-2-Disease API."""
if not HF_TOKEN:
error_msg = (
"Error analyzing symptoms: HF_TOKEN not set. Please set HF_TOKEN in Space secrets at "
"https://huggingface.co/spaces/your-username/HealthVoiceAnalyzer/settings."
)
print(error_msg)
return error_msg, 0.0
try:
if not text or "Error transcribing" in text:
return "No valid transcription for analysis.", 0.0
payload = {"inputs": text}
response = requests.post(SYMPTOM_API_URL, headers=HEADERS, json=payload)
response.raise_for_status()
result = response.json()
print(f"Symptom API response: {result}")
if result and isinstance(result, list) and len(result) > 0:
prediction = result[0][0]["label"]
score = result[0][0]["score"]
print(f"Health Prediction: {prediction}, Score: {score:.4f}")
return prediction, score
return "No health condition predicted", 0.0
except requests.exceptions.HTTPError as e:
error_msg = f"Error analyzing symptoms: {str(e)}"
if e.response.status_code == 401:
error_msg = (
"Error analyzing symptoms: Unauthorized. Please check HF_TOKEN in Space secrets at "
"https://huggingface.co/spaces/your-username/HealthVoiceAnalyzer/settings. "
"Ensure token has Inference API access (get at https://huggingface.co/settings/tokens)."
)
print(f"Symptom API error: {error_msg}, Status: {e.response.status_code}")
return error_msg, 0.0
except Exception as e:
error_msg = f"Error analyzing symptoms: {str(e)}"
print(error_msg)
return error_msg, 0.0
def analyze_voice(audio_file):
"""Analyze voice for health indicators."""
try:
# Ensure unique file name to avoid Gradio reuse
unique_path = f"/tmp/gradio/{datetime.now().strftime('%Y%m%d%H%M%S%f')}_{os.path.basename(audio_file)}"
os.rename(audio_file, unique_path)
audio_file = unique_path
# Log audio file info
file_hash = compute_file_hash(audio_file)
print(f"Processing audio file: {audio_file}, Hash: {file_hash}")
# Load audio to verify format
audio, sr = librosa.load(audio_file, sr=16000)
print(f"Audio shape: {audio.shape}, Sampling rate: {sr}, Duration: {len(audio)/sr:.2f}s, Mean: {np.mean(audio):.4f}, Std: {np.std(audio):.4f}")
# Transcribe audio
transcription = transcribe_audio(audio_file)
if "Error transcribing" in transcription:
return transcription
# Analyze symptoms
prediction, score = analyze_symptoms(transcription)
if "Error analyzing" in prediction:
return prediction
# Generate feedback
if prediction == "No health condition predicted":
feedback = "No significant health indicators detected."
else:
feedback = f"Possible health condition: {prediction} (confidence: {score:.4f}). Consult a doctor."
feedback += f"\n\n**Debug Info**: Transcription = '{transcription}', Prediction = {prediction}, Confidence = {score:.4f}, File Hash = {file_hash}"
feedback += "\n**Disclaimer**: This is not a diagnostic tool. Consult a healthcare provider for medical advice."
# Store in Salesforce
if sf:
store_in_salesforce(audio_file, feedback, transcription, prediction, score)
# Clean up temporary audio file
try:
os.remove(audio_file)
print(f"Deleted temporary audio file: {audio_file}")
except Exception as e:
print(f"Failed to delete audio file: {str(e)}")
return feedback
except Exception as e:
return f"Error processing audio: {str(e)}"
def store_in_salesforce(audio_file, feedback, transcription, prediction, score):
"""Store analysis results in Salesforce."""
try:
sf.HealthAssessment__c.create({
"AssessmentDate__c": datetime.utcnow().isoformat(),
"Feedback__c": feedback,
"Transcription__c": transcription,
"Prediction__c": prediction,
"Confidence__c": float(score),
"AudioFileName__c": os.path.basename(audio_file)
})
except Exception as e:
print(f"Failed to store in Salesforce: {str(e)}")
def test_with_sample_audio():
"""Test the app with sample audio files."""
samples = ["audio_samples/sample.wav", "audio_samples/common_voice_en.wav"]
results = []
for sample in samples:
if os.path.exists(sample):
results.append(analyze_voice(sample))
else:
results.append(f"Sample not found: {sample}")
return "\n".join(results)
# Gradio interface
iface = gr.Interface(
fn=analyze_voice,
inputs=gr.Audio(type="filepath", label="Record or Upload Voice"),
outputs=gr.Textbox(label="Health Assessment Feedback"),
title="Health Voice Analyzer",
description="Record or upload a voice sample describing symptoms for preliminary health assessment. Supports English (transcription), with symptom analysis in English. Ensure HF_TOKEN is set in Space secrets."
)
if __name__ == "__main__":
print(test_with_sample_audio())
iface.launch(server_name="0.0.0.0", server_port=7860) |