Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os | |
| from datetime import datetime | |
| from google import genai | |
| from google.genai import types | |
| # --- 1. PAGE CONFIG & MODERN CSS --- | |
| st.set_page_config(page_title="Abyssinia Scribe", page_icon="π₯", layout="wide") | |
| # Custom CSS for "ChatGPT Style" Output - Clean Sans-Serif & Modern Spacing | |
| st.markdown(""" | |
| <style> | |
| /* ChatGPT-style Container */ | |
| .chat-gpt-style { | |
| background-color: #ffffff; | |
| color: #343541; | |
| padding: 40px; | |
| border-radius: 12px; | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| line-height: 1.6; | |
| border: 1px solid #e5e5e5; | |
| box-shadow: 0 4px 24px rgba(0,0,0,0.08); | |
| max-width: 800px; | |
| margin: auto; | |
| } | |
| /* Clinical Headers */ | |
| .note-section-header { | |
| color: #10a37f; /* ChatGPT Green accent */ | |
| font-weight: 600; | |
| font-size: 1.1em; | |
| margin-top: 20px; | |
| margin-bottom: 8px; | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| /* Accurate Signature */ | |
| .clinical-sig { | |
| margin-top: 40px; | |
| padding-top: 20px; | |
| border-top: 1px solid #f0f0f0; | |
| color: #6e6e80; | |
| font-size: 0.9em; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # API Initialization | |
| client = genai.Client(api_key=os.environ.get("GOOGLE_API_KEY")) | |
| # --- 2. THE UI --- | |
| st.title("π₯ Abyssinia Intelligence Scribe") | |
| col1, col2 = st.columns([1, 1], gap="large") | |
| with col1: | |
| st.subheader("ποΈ Input Consultation") | |
| audio_file = st.audio_input("Record Conversation") | |
| text_backup = st.text_area("Or type/paste notes here:", height=250) | |
| generate_btn = st.button("Finalize Scribe Report", type="primary") | |
| with col2: | |
| st.subheader("π Final Medical Note") | |
| if generate_btn: | |
| # Prepare content parts | |
| parts = [] | |
| if audio_file: | |
| parts.append(types.Part.from_bytes(data=audio_file.read(), mime_type="audio/wav")) | |
| elif text_backup: | |
| parts.append(types.Part.from_text(text=text_backup)) | |
| if not parts: | |
| st.error("Error: No consultation data detected.") | |
| else: | |
| with st.spinner("Generating document..."): | |
| try: | |
| # Request structured data from Gemini 3.0 Flash | |
| response = client.models.generate_content( | |
| model="gemini-3-flash-preview", | |
| config=types.GenerateContentConfig( | |
| system_instruction="Create a detailed, structured medical SOAP note. Format sections clearly.", | |
| temperature=0.2 | |
| ), | |
| contents=parts | |
| ) | |
| # Formatting text to look "ChatGPT attractive" rather than code-like | |
| formatted_output = response.text.replace("### ", "<div class='note-section-header'>") | |
| formatted_output = formatted_output.replace("\n", "<br>") | |
| # Get Local Ethiopia/Server Time | |
| now = datetime.now() | |
| timestamp = now.strftime("%d %B %Y at %H:%M") | |
| # Rendering the HTML | |
| st.markdown(f""" | |
| <div class="chat-gpt-style"> | |
| {formatted_output} | |
| <div class="clinical-sig"> | |
| <b>Digitally Authenticated:</b> Abyssinia AI Scribe Engine<br> | |
| <b>Finalized on:</b> {timestamp}<br> | |
| <b>Reference ID:</b> ABY-{now.strftime('%m%d-%H%M')} | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.download_button("Export Clinical Note", response.text) | |
| except Exception as e: | |
| st.error(f"Scribe Error: {e}") |