File size: 10,104 Bytes
a743eab
8593387
7166f82
de062b2
f1f0624
072be46
2d616b6
eeabe0b
ef60d1f
106e94e
 
f1f0624
f2474c0
f1f0624
7166f82
5cd099c
7166f82
 
 
2f83d91
7166f82
eeabe0b
0b85370
 
582cdaa
7166f82
 
b6b8268
 
 
 
 
5a6a7c2
b6b8268
 
f77b91e
 
 
 
b6b8268
 
 
7166f82
226cf48
 
2b28e2a
7166f82
 
 
 
51946fc
582cdaa
7166f82
51b3fe0
fcc60cf
51b3fe0
7166f82
8920538
ef60d1f
eeabe0b
7166f82
 
 
ef60d1f
eeabe0b
37fb05d
 
 
 
 
 
 
 
 
4e4575b
 
 
 
 
 
 
 
 
 
 
 
 
7166f82
 
 
8593387
4e4575b
 
 
8593387
8822d53
eeabe0b
8822d53
7166f82
 
8822d53
b6b8268
 
 
1f40843
 
 
 
 
 
 
 
 
 
 
 
b6b8268
7166f82
f1f0624
 
 
ef60d1f
eeabe0b
37fb05d
ef60d1f
 
1f40843
ef60d1f
8822d53
eeabe0b
5a6a7c2
b6b8268
2169527
58a2bd0
072be46
57f1a14
 
 
 
 
 
 
 
 
 
 
 
fcc60cf
51b3fe0
57f1a14
 
8822d53
f1f0624
 
 
 
 
 
 
 
 
0d9be8f
2d616b6
eeabe0b
2d616b6
22bb342
2d616b6
 
 
 
cc7d78f
 
2d616b6
 
 
 
 
 
 
 
 
 
 
 
 
cc7d78f
 
 
2d616b6
 
 
862e936
cc7d78f
 
eeabe0b
cc7d78f
 
 
 
8920538
37fb05d
 
85f4493
c880135
09c32d0
 
 
9de422b
 
09c32d0
 
 
fe72ac7
 
 
 
0161e86
09c32d0
 
 
518953a
09c32d0
f736e15
 
 
 
 
 
 
09c32d0
 
fe72ac7
 
57f1a14
 
09c32d0
4222cb7
 
 
 
 
f736e15
4222cb7
 
 
 
 
 
fd256c4
4222cb7
 
3d5e124
d669981
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
import gradio as gr
import assemblyai as aai
from transformers import pipeline
import os
from supabase import create_client, Client
from datetime import datetime
import csv
from typing import Optional

# Add your AssemblyAI API key as Environment Variable
aai.settings.api_key = os.environ['Assembly']
url: str = os.environ['DBUrl']
key: str = os.environ['DBKey']

# Initialize question answering pipeline
question_answerer = pipeline("question-answering", model='distilbert-base-cased-distilled-squad')

# List of questions
questions = [
    "How old is the patient?",
    "What is the gender?",
    "What is the chief complaint regarding the patient's oral health?",
    "List the Medical history mentioned",
    "Give the Dental history in detail",
    "Please give all the clinical findings which were listed"
]

# List of form fields in the correct order
form_fields = [
    "Age",
    "Gender",
    "Chief complaint",
    "Medical history",
    "Dental history",
    "Clinical Findings",
    "Referred to",
    "Treatment plan",
    "Calculus",
    "Stains"
]

# Oral Health Assessment Form
oral_health_assessment_form = [
    "Doctor’s Name",
    "Location",
    "Patient’s Name",
    "Age",
    "Gender",
    "Chief complaint",
    "Medical history",
    "Dental history",
    "Clinical Findings",
    "Treatment plan",
    "Referred to",
    "Calculus",
    "Stains"
]

# Function to generate answers for the questions
def generate_answer(question: str, context: str) -> str:
    result = question_answerer(question=question, context=context)
    return result['answer']

# Function to handle audio recording and transcription
def transcribe_audio(audio_path: str) -> str:
    print(f"Received audio file at: {audio_path}")
    
    # Check if the file exists and is not empty
    if not os.path.exists(audio_path):
        return "Error: Audio file does not exist."
    
    if os.path.getsize(audio_path) == 0:
        return "Error: Audio file is empty."
    
    try:
        # Transcribe the audio file using AssemblyAI
        transcriber = aai.Transcriber()
        print("Starting transcription...")
        transcript = transcriber.transcribe(audio_path)
        
        print("Transcription process completed.")
        
        # Handle the transcription result
        if transcript.status == aai.TranscriptStatus.error:
            print(f"Error during transcription: {transcript.error}")
            return transcript.error
        else:
            context = transcript.text
            print(f"Transcription text: {context}")
            return context
    
    except Exception as e:
        print(f"Exception occurred: {e}")
        return str(e)

# Function to fill in the answers for the text boxes
def fill_textboxes(context: str) -> dict:
    answers = []
    for question in questions:
        answer = generate_answer(question, context)
        answers.append(answer)
    
    # Map answers to form fields in the correct order
    return {
        "Age": answers[0] if len(answers) > 0 else "",
        "Gender": answers[1] if len(answers) > 1 else "",
        "Chief complaint": answers[2] if len(answers) > 2 else "",
        "Medical history": answers[3] if len(answers) > 3 else "",
        "Dental history": answers[4] if len(answers) > 4 else "",
        "Clinical Findings": answers[5] if len(answers) > 5 else "",
        "Referred to": "",  # Default value
        "Treatment plan": "",  # Default value
        "Calculus": "",  # Default value
        "Stains": "",  # Default value
        "Doctor’s Name": "",  # Default value
        "Location": ""  # Default value
    }

# Supabase configuration
supabase: Client = create_client(url, key)

# Main Gradio app function
def main(audio: str, doctor_name: str, location: str) -> list:
    context = transcribe_audio(audio)
    
    if "Error" in context:
        return [context] * len(oral_health_assessment_form)  # Adjust for the number of fields
    
    answers = fill_textboxes(context)
    answers_list = [doctor_name, location, ""]  # Initial patient name field empty
    answers_list += [answers.get(field, "") for field in form_fields]
    return answers_list

def save_answers(doctor_name: str, location: str, patient_name: str, age: str, gender: str, chief_complaint: str, medical_history: str, dental_history: str, clinical_findings: str, treatment_plan: str, referred_to: str, Calculus: str, stains: str) -> str:
    current_datetime = datetime.now().isoformat()
    answers_dict = {
        "Doctor’s Name": doctor_name,
        "Location": location,
        "Patient’s Name": patient_name,
        "Age": age,
        "Gender": gender,
        "Chief complaint": chief_complaint,
        "Medical history": medical_history,
        "Dental history": dental_history,
        "Clinical Findings": clinical_findings,
        "Treatment plan": treatment_plan,
        "Referred to": referred_to,
        "Calculus": Calculus,
        "Stains": stains,
        "Submission Date and Time": current_datetime
    }
    print("Saved answers:", answers_dict)
    
    # Insert data into Supabase
    try:
        response = supabase.table('oral_health_assessments').insert(answers_dict).execute()
        print("Data inserted into Supabase:", response.data)
        return f"Saved answers: {answers_dict}"
    except Exception as e:
        print(f"Error inserting data into Supabase: {e}")
        return f"Error saving answers: {e}"

# Function to download table as CSV
def download_table_to_csv() -> Optional[str]:
    # Fetch data from Supabase table
    response = supabase.table("oral_health_assessments").select("*").execute()
    
    # Check if data is available
    if not response.data:
        print("No data found in the table.")
        return None

    data = response.data

    # Prepare CSV data
    csv_data = []

    # Add header row
    if len(data) > 0:
        csv_data.append(data[0].keys())

    # Add data rows
    for row in data:
        csv_data.append(row.values())

    # Save CSV data to file (replace 'your_table.csv' with desired filename)
    csv_file = "your_table.csv"
    with open(csv_file, "w", newline='') as f:
        writer = csv.writer(f)
        writer.writerows(csv_data)

    print("Downloaded table oral_health_assessments")
    return csv_file

def gradio_download() -> Optional[str]:
    file_path = download_table_to_csv()
    if file_path:
        return file_path
    return None

# Create the Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# OHA Form Filler App")
    
    with gr.Tabs() as tabs:
        # Default tab for Doctor's Name and Location
        with gr.Tab("Doctor Info"):
            doctor_name_input = gr.Textbox(label="Doctor's Name", interactive=True)
            location_input = gr.Textbox(label="Location", interactive=True)
            submit_button = gr.Button("Submit")
            info_output = gr.HTML(label="Submitted Info")
            
            def submit_info(name, loc):
                return f"Doctor's Name: {name}<br>Location: {loc}"
            
            submit_button.click(fn=submit_info, inputs=[doctor_name_input, location_input], outputs=info_output)
        
        # Second tab for OHA Form
        with gr.Tab("OHA Form"):
            audio_input = gr.Audio(type="filepath", label="Record your audio", elem_id="audio_input")
            transcribe_button = gr.Button("Transcribe and Generate Form", elem_id="transcribe_button", interactive=False)
            
            def enable_transcribe_button(audio):
                if audio:
                    return gr.update(interactive=True)
                return gr.update(interactive=False)
            
            audio_input.change(fn=enable_transcribe_button, inputs=audio_input, outputs=transcribe_button)

            with gr.Row(elem_id="textboxes_row"):
                with gr.Column():
                    doctor_name_display = gr.Textbox(label="Doctor’s Name", value="", interactive=False)
                    location_display = gr.Textbox(label="Location", value="", interactive=False)
                    patient_name_input = gr.Textbox(label="Patient’s Name", value="", interactive=True)
                    textboxes_left = [gr.Textbox(label=oral_health_assessment_form[i], value="", interactive=True) for i in range(3, len(oral_health_assessment_form)//2)]
                with gr.Column():
                    textboxes_right = [gr.Textbox(label=oral_health_assessment_form[i], value="", interactive=True) for i in range(len(oral_health_assessment_form)//2, len(oral_health_assessment_form)-3)]
                    textboxes_right.append(gr.Textbox(label="Clinical Findings", interactive=True))
                    textboxes_right.append(gr.Dropdown(choices=["NONE", "ORAL MEDICINE & RADIOLOGY", "PERIODONTICS", "ORAL SURGERY", "CONSERVATIVE AND ENDODONTICS", "PROSTHODONTICS", "PEDODONTICS", "ORTHODONTICS"], value="NONE", label="Referred to", interactive=True))
                    textboxes_right.append(gr.Dropdown(choices=["+", "++", "+++"], label="Calculus", interactive=True))
                    textboxes_right.append(gr.Dropdown(choices=["-", "+", "++", "+++"], label="Stains", interactive=True))
                    textboxes_right.append(gr.Dropdown(choices=["Scaling", "Filling", "Pulp therapy/RCT", "Extraction", "Medication"], label="Treatment plan", interactive=True))
            oha_output = gr.Textbox(label="OHA Output", value="", interactive=False)
            save_button = gr.Button("Save to Supabase", elem_id="save_button", interactive=True)
            transcribe_button.click(fn=main, inputs=[audio_input, doctor_name_display, location_display], outputs=[oha_output])
            save_button.click(fn=save_answers, inputs=[doctor_name_display, location_display, patient_name_input] + textboxes_left + textboxes_right, outputs=[oha_output])
        
        with gr.Tab("Download Data"):
            download_button = gr.Button("Download CSV")
            download_output = gr.File()
            download_button.click(fn=gradio_download, outputs=download_output)

demo.launch()