Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| from dotenv import load_dotenv | |
| from ai_core import analyze_image_with_query | |
| from audio_utils import transcribe_with_groq, text_to_speech_with_gtts | |
| from image_utils import encode_image | |
| load_dotenv() | |
| # --- Configuration --- | |
| GROQ_API_KEY = os.environ.get("GROQ_API_KEY") | |
| STT_MODEL = "whisper-large-v3" | |
| VISION_MODEL = "meta-llama/llama-4-scout-17b-16e-instruct" | |
| SYSTEM_PROMPT = """You are SymptoScan MD, an AI medical assistant. Your role is to act as a professional, empathetic, and knowledgeable doctor. | |
| When analyzing the user's symptoms and any provided medical images, please follow these guidelines: | |
| 1. **Analyze Symptoms:** Carefully consider the user's described symptoms from the transcript. | |
| 2. **Analyze Image:** If an image is provided, analyze it in detail for any visible signs related to the symptoms. | |
| 3. **Provide a Possible Diagnosis:** Based on the text and image, provide a potential diagnosis or a few possible explanations for the symptoms. | |
| 4. **Suggest Next Steps:** Recommend clear and safe next steps for the user. This could include seeing a specialist, trying over-the-counter remedies, or making lifestyle changes. | |
| 5. **Maintain a Professional Tone:** Your response should be clear, concise, and easy for a non-medical person to understand. | |
| 6. **Include a Disclaimer:** ALWAYS end your response with the following disclaimer: 'Disclaimer: I am an AI assistant and not a real doctor. This is not a real medical diagnosis. Please consult a qualified healthcare professional for any medical concerns.' | |
| Your primary goal is to be helpful and safe. Do not provide any information that could be dangerous or misleading. | |
| """ | |
| # --- Main Processing Function --- | |
| def process_inputs(audio_filepath, image_filepath): | |
| transcript = "No audio was provided." | |
| if audio_filepath: | |
| try: | |
| transcript = transcribe_with_groq( | |
| stt_model=STT_MODEL, | |
| audio_filepath=audio_filepath, | |
| groq_api_key=GROQ_API_KEY | |
| ) | |
| except Exception as e: | |
| return f"Error in transcription: {e}", "", None | |
| if image_filepath: | |
| try: | |
| encoded_image = encode_image(image_filepath) | |
| query = f"{SYSTEM_PROMPT}\n\nUser symptoms: {transcript}" | |
| doctor_response = analyze_image_with_query( | |
| query=query, | |
| model=VISION_MODEL, | |
| encoded_image=encoded_image, | |
| groq_api_key=GROQ_API_KEY | |
| ) | |
| except Exception as e: | |
| return transcript, f"Error in AI analysis: {e}", None | |
| else: | |
| doctor_response = "No image provided. Please upload an image for analysis." | |
| try: | |
| voice_path = text_to_speech_with_gtts( | |
| input_text=doctor_response, | |
| output_filepath="symptoscan_md_response.mp3" | |
| ) | |
| except Exception as e: | |
| return transcript, doctor_response, f"Error in generating audio: {e}" | |
| return transcript, doctor_response, voice_path | |
| # --- Gradio UI --- | |
| professional_theme = gr.themes.Soft( | |
| primary_hue="teal", | |
| secondary_hue="blue", | |
| neutral_hue="slate", | |
| ).set( | |
| body_background_fill="#F0F4F8", | |
| ) | |
| with gr.Blocks(title="SymptoScan MD", theme=professional_theme, css=".gradio-container { max-width: 900px !important; margin: auto !important; }") as demo: | |
| gr.Markdown( | |
| """ | |
| # π©Ί SymptoScan MD | |
| ### Your AI-Powered Visual Health Assistant | |
| Upload a medical image (e.g., a skin condition) and describe your symptoms. Our AI will provide a preliminary analysis and suggest next steps. | |
| """ | |
| ) | |
| with gr.Row(equal_height=True): | |
| with gr.Column(scale=1): | |
| audio_input = gr.Audio(sources=["microphone"], type="filepath", label="π€ Record Your Symptoms") | |
| image_input = gr.Image(type="filepath", label="πΌοΈ Upload Medical Image") | |
| submit_btn = gr.Button("Analyze Symptoms", variant="primary") | |
| with gr.Column(scale=2): | |
| transcript_output = gr.Textbox(label="π Your Symptoms (Transcribed)", lines=4, interactive=False) | |
| response_output = gr.Textbox(label="π©ββοΈ AI Doctor's Analysis", lines=8, interactive=False) | |
| audio_output = gr.Audio(label="π AI Voice Response", interactive=False) | |
| # --- Logic --- | |
| submit_btn.click( | |
| fn=process_inputs, | |
| inputs=[audio_input, image_input], | |
| outputs=[transcript_output, response_output, audio_output], | |
| api_name="analyze" | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(debug=True) |