spriambada3's picture
deploy login
fd19f35
raw
history blame
6.81 kB
import os
import json
import re
import gradio as gr
from google import genai
from google.genai import types
import asyncio
def audio_from_bytes(audio_file_path: str):
"""Converts an audio file into Gemini-compatible format."""
try:
with open(audio_file_path, "rb") as f:
audio_data = f.read()
mime_type = "audio/mp3" # Adjust based on your audio type
return types.Part.from_bytes(data=audio_data, mime_type=mime_type)
except FileNotFoundError:
return "Error: Audio file not found!"
except Exception as e:
return f"An error occurred: {e}"
def transcribe_and_summarize(audio_file, session):
"""Processes audio with Gemini API and returns a SOAP summary."""
if audio_file is None:
return "No audio file uploaded."
# Ensure API Key is set
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
if not GEMINI_API_KEY:
return "Error: GEMINI_API_KEY environment variable is missing."
asyncio.set_event_loop(asyncio.new_event_loop())
client = genai.Client(api_key=GEMINI_API_KEY)
model = "gemini-2.0-flash"
# Prepare the request
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(
text="""Anda adalah asisten medis yang membantu dokter dalam menyusun catatan medis dalam bentuk paragraf menggunakan bahasa Indonesia.
Buat ringkasan SOAP berdasarkan percakapan dokter dan pasien dalam format berikut:
Subjective:
ICD10:
Objective:
Assessment:
Plan:
Identifikasi dan berikan saran dalam bahasa Indonesia tindakan logis selanjutnya dalam format:
ICD10:
Obat:
Laboratorium:
Radiologi:
"""
),
audio_from_bytes(audio_file),
],
)
]
generate_content_config = types.GenerateContentConfig(
temperature=0,
top_p=0.95,
top_k=40,
max_output_tokens=8192,
response_mime_type="text/plain",
)
# Process the audio
response_text = ""
# for chunk in client.models.generate_content_stream(
# model=model,
# contents=contents,
# config=generate_content_config,
# ):
# response_text += chunk.text
counter_display, session = click_button(session)
return response_text, counter_display, session
DATA_FILE = "user_data.json"
def load_user_data():
"""Load user data from JSON file."""
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r") as file:
return json.load(file)
return {} # Return empty dictionary if no data
def save_user_data(username, email):
"""Save user data to JSON file with default counter = 10 if new."""
data = load_user_data()
if username not in data: # New user
data[username] = {"email": email, "counter": 10} # Set default counter to 10
with open(DATA_FILE, "w") as file:
json.dump(data, file, indent=4)
return data
def is_valid_wa(username):
"""Check if username is all numbers, at least 11 characters, and starts with 08 or 62."""
return re.fullmatch(r"^(08|62)\d{9,}$", username) is not None
def is_valid_email(email):
"""Check if email format is valid."""
return re.fullmatch(r"^[\w\.-]+@[\w\.-]+\.\w+$", email) is not None
def login(username, email, session):
"""Handles user login or registration with validation."""
if not is_valid_wa(username):
return (
"❌ Invalid WA! Nomor WA minimal 12 digits dimulai '08' atau '62'.",
session,
gr.update(visible=True),
gr.update(visible=False),
)
if not is_valid_email(email):
return (
"❌ Invalid email format! Please enter a valid email.",
session,
gr.update(visible=True),
gr.update(visible=False),
)
data = save_user_data(username, email) # Save or retrieve user data
session["username"] = username
session["counter"] = data[username]["counter"]
return "", session, gr.update(visible=False), gr.update(visible=True)
def click_button(session):
"""Decrease counter on button click."""
if session["counter"] > 0:
session["counter"] -= 1
# Update the user data in JSON file
data = load_user_data()
data[session["username"]]["counter"] = session["counter"]
with open(DATA_FILE, "w") as file:
json.dump(data, file, indent=4)
if session["counter"] == 0:
return (
f"⚠️ Quota habis. Silahkan mengunjungi https://ehealth.co.id atau WA 6285777779926",
session,
)
return f"Counter: {session['counter']}", session
else:
return (
f"⚠️ Quota habis. Silahkan mengunjungi https://ehealth.co.id atau WA 6285777779926",
session,
)
# Gradio Interface
with gr.Blocks() as demo:
session = gr.State({"username": None, "counter": 0}) # Manage session state
gr.Markdown("# 🛡️ eHealth.co.id Scribe")
# Login Section
login_block = gr.Column(visible=True)
with login_block:
email_input = gr.Textbox(label="Email")
username_input = gr.Textbox(label="WA", type="password") # Hide input
login_button = gr.Button("🔑 Login / Register")
gr.Markdown(
"""### dengan login saya menyetujui ketentuan penggunaan data eHealth.co.id dan tidak akan menuntut perusahaan eHealth.co.id untuk uji coba gratis AI Transcribe ini
saya memahami bahwa tidak ada data suara maupun tulisan medis yang akan disimpan oleh perusahaan
seluruh data yang saya sediakan adalah data yang benar dan tidak bermaksud melanggar hukum
## Setelah quota habis, Silahkan mengunjungi https://ehealth.co.id atau WA 6285777779926"""
)
output_text = gr.Textbox(label="Status", interactive=False)
# Main User Interface (After Login)
user_block = gr.Column(visible=False)
with user_block:
counter_display = gr.Textbox(label="Status Message", interactive=False)
gr.Interface(
fn=transcribe_and_summarize,
inputs=[gr.Audio(type="filepath", sources="microphone"), session],
outputs=["text", counter_display, session],
title="eH Transcription",
description="pastikan HP/Laptop memiliki microphone untuk merekam percakapan dokter-pasien menjadi rekam medis SOAP",
allow_flagging="never",
)
# Login button action
login_button.click(
login,
[username_input, email_input, session],
[output_text, session, login_block, user_block],
)
demo.launch()