Updated audio function
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
|
| 4 |
# # Occasio - Event Management Assistant
|
| 5 |
|
| 6 |
-
# In[
|
| 7 |
|
| 8 |
|
| 9 |
# imports
|
|
@@ -19,7 +19,7 @@ import google.generativeai as genai
|
|
| 19 |
import gradio as gr
|
| 20 |
|
| 21 |
|
| 22 |
-
# In[
|
| 23 |
|
| 24 |
|
| 25 |
# Load environment variables in a file called .env
|
|
@@ -46,7 +46,7 @@ else:
|
|
| 46 |
print("Google API Key not set")
|
| 47 |
|
| 48 |
|
| 49 |
-
# In[
|
| 50 |
|
| 51 |
|
| 52 |
# Connect to OpenAI, Anthropic and Google
|
|
@@ -61,7 +61,7 @@ genai.configure()
|
|
| 61 |
GOOGLE_MODEL = "gemini-2.0-flash"
|
| 62 |
|
| 63 |
|
| 64 |
-
# In[
|
| 65 |
|
| 66 |
|
| 67 |
system_message = "You are called \"EventAI\", a virtual assistant for an Elementary school called Eagle Elementary School. You can help users by giving \
|
|
@@ -73,7 +73,7 @@ system_message += "You might be asked to list the questions asked by the user so
|
|
| 73 |
list the questions and respond"
|
| 74 |
|
| 75 |
|
| 76 |
-
# In[
|
| 77 |
|
| 78 |
|
| 79 |
# Some imports for handling images
|
|
@@ -83,7 +83,7 @@ from io import BytesIO
|
|
| 83 |
from PIL import Image
|
| 84 |
|
| 85 |
|
| 86 |
-
# In[
|
| 87 |
|
| 88 |
|
| 89 |
def artist(event_text):
|
|
@@ -99,7 +99,7 @@ def artist(event_text):
|
|
| 99 |
return Image.open(BytesIO(image_data))
|
| 100 |
|
| 101 |
|
| 102 |
-
# In[
|
| 103 |
|
| 104 |
|
| 105 |
import base64
|
|
@@ -115,14 +115,16 @@ def talker(message):
|
|
| 115 |
|
| 116 |
audio_stream = BytesIO(response.content)
|
| 117 |
output_filename = "output_audio.mp3"
|
|
|
|
| 118 |
with open(output_filename, "wb") as f:
|
| 119 |
f.write(audio_stream.read())
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
# Play the generated audio
|
| 122 |
-
display(Audio(output_filename, autoplay=True))
|
| 123 |
|
| 124 |
-
|
| 125 |
-
# In[ ]:
|
| 126 |
|
| 127 |
|
| 128 |
school_events = [
|
|
@@ -178,7 +180,7 @@ school_events = [
|
|
| 178 |
]
|
| 179 |
|
| 180 |
|
| 181 |
-
# In[
|
| 182 |
|
| 183 |
|
| 184 |
def get_event_details(query):
|
|
@@ -200,7 +202,7 @@ def get_event_details(query):
|
|
| 200 |
#
|
| 201 |
# Well, kinda.
|
| 202 |
|
| 203 |
-
# In[
|
| 204 |
|
| 205 |
|
| 206 |
# for claude
|
|
@@ -223,7 +225,7 @@ tools_claude = [
|
|
| 223 |
]
|
| 224 |
|
| 225 |
|
| 226 |
-
# In[
|
| 227 |
|
| 228 |
|
| 229 |
# For GPT
|
|
@@ -245,14 +247,14 @@ events_function_gpt = {
|
|
| 245 |
}
|
| 246 |
|
| 247 |
|
| 248 |
-
# In[
|
| 249 |
|
| 250 |
|
| 251 |
# And this is included in a list of tools:
|
| 252 |
tools_gpt = [{"type": "function", "function": events_function_gpt}]
|
| 253 |
|
| 254 |
|
| 255 |
-
# In[
|
| 256 |
|
| 257 |
|
| 258 |
#Gemini function declaration structure
|
|
@@ -287,7 +289,7 @@ gemini_event_details = [{
|
|
| 287 |
]
|
| 288 |
|
| 289 |
|
| 290 |
-
# In[
|
| 291 |
|
| 292 |
|
| 293 |
def chat_claude(history):
|
|
@@ -352,7 +354,7 @@ def chat_claude(history):
|
|
| 352 |
for text in stream.text_stream:
|
| 353 |
result += text or ""
|
| 354 |
yield result, None
|
| 355 |
-
talker(result)
|
| 356 |
#image= artist(tool_input.get('event_text'))
|
| 357 |
yield result, image
|
| 358 |
else:
|
|
@@ -361,7 +363,7 @@ def chat_claude(history):
|
|
| 361 |
for i in range(0, len(response), chunk_size):
|
| 362 |
yield response[:i + chunk_size], None
|
| 363 |
time.sleep(0.05) #Simulate streaming delay
|
| 364 |
-
talker(response)
|
| 365 |
#image= artist(tool_input.get('event_text'))
|
| 366 |
yield response, None
|
| 367 |
except Exception as e:
|
|
@@ -371,7 +373,7 @@ def chat_claude(history):
|
|
| 371 |
|
| 372 |
|
| 373 |
|
| 374 |
-
# In[
|
| 375 |
|
| 376 |
|
| 377 |
def chat_gpt(history):
|
|
@@ -403,7 +405,7 @@ def chat_gpt(history):
|
|
| 403 |
for chunk in stream:
|
| 404 |
result += chunk.choices[0].delta.content or ""
|
| 405 |
yield result, None
|
| 406 |
-
talker(result)
|
| 407 |
yield result, image
|
| 408 |
else:
|
| 409 |
reply = response.choices[0].message.content
|
|
@@ -411,7 +413,7 @@ def chat_gpt(history):
|
|
| 411 |
for i in range(0, len(reply), chunk_size):
|
| 412 |
yield reply[:i + chunk_size], None
|
| 413 |
time.sleep(0.05)
|
| 414 |
-
talker(reply)
|
| 415 |
#image= artist("No such event")
|
| 416 |
yield reply, None
|
| 417 |
except Exception as e:
|
|
@@ -420,11 +422,11 @@ def chat_gpt(history):
|
|
| 420 |
yield error_message, None
|
| 421 |
|
| 422 |
|
| 423 |
-
# In[
|
| 424 |
|
| 425 |
|
| 426 |
def chat_gemini(history):
|
| 427 |
-
print(f"\
|
| 428 |
history_gemini = [{'role': m['role'], 'parts': [{'text': m['content']}]} if 'content' in m #if content exists, change it to parts format
|
| 429 |
else {'role': m['role'], 'parts': m['parts']} if 'parts' in m #else if parts exists, just copy it as it is
|
| 430 |
else {'role': m['role']} for m in history] #else neither content nor parts exists, copy only the role ignoring all other keys like metadata, options etc
|
|
@@ -463,7 +465,7 @@ def chat_gemini(history):
|
|
| 463 |
result += chunk.candidates[0].content.parts[0].text or ""
|
| 464 |
#print(f"REsult is \n{result}\n")
|
| 465 |
yield result, None
|
| 466 |
-
talker(result)
|
| 467 |
yield result, image
|
| 468 |
#print(f"REsult is \n{result}\n")
|
| 469 |
else:
|
|
@@ -472,21 +474,18 @@ def chat_gemini(history):
|
|
| 472 |
for i in range(0, len(reply), chunk_size):
|
| 473 |
yield reply[:i + chunk_size], None
|
| 474 |
time.sleep(0.05)
|
| 475 |
-
talker(reply)
|
| 476 |
#image= artist("No such event")
|
| 477 |
yield reply, None
|
| 478 |
|
| 479 |
except Exception as e:
|
| 480 |
error_message = "Apologies, my server is acting weird. Please try again later."
|
| 481 |
print(e)
|
| 482 |
-
yield error_message, None
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
|
| 487 |
|
| 488 |
|
| 489 |
-
# In[
|
| 490 |
|
| 491 |
|
| 492 |
def call_and_process_model_responses(fn_name, chatbot):#, response, image):
|
|
@@ -502,7 +501,7 @@ def call_and_process_model_responses(fn_name, chatbot):#, response, image):
|
|
| 502 |
|
| 503 |
|
| 504 |
|
| 505 |
-
# In[
|
| 506 |
|
| 507 |
|
| 508 |
def handle_tool_call(event_text):
|
|
@@ -518,7 +517,7 @@ def handle_tool_call(event_text):
|
|
| 518 |
|
| 519 |
|
| 520 |
|
| 521 |
-
# In[
|
| 522 |
|
| 523 |
|
| 524 |
def process_chosen_model(chatbot, model):
|
|
@@ -535,7 +534,7 @@ def process_chosen_model(chatbot, model):
|
|
| 535 |
|
| 536 |
|
| 537 |
|
| 538 |
-
# In[
|
| 539 |
|
| 540 |
|
| 541 |
# More involved Gradio code as we're not using the preset Chat interface!
|
|
@@ -579,9 +578,16 @@ with gr.Blocks(css="""
|
|
| 579 |
|
| 580 |
entry.submit(do_entry, inputs=[entry, chatbot], outputs=[entry, chatbot]).then(
|
| 581 |
process_chosen_model, inputs=[chatbot, model], outputs=[chatbot, image_output]
|
|
|
|
|
|
|
| 582 |
)
|
|
|
|
| 583 |
clear.click(lambda: None, inputs=None, outputs=chatbot, queue=False)
|
| 584 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
ui.launch(inbrowser=True)
|
| 586 |
|
| 587 |
|
|
|
|
| 3 |
|
| 4 |
# # Occasio - Event Management Assistant
|
| 5 |
|
| 6 |
+
# In[1]:
|
| 7 |
|
| 8 |
|
| 9 |
# imports
|
|
|
|
| 19 |
import gradio as gr
|
| 20 |
|
| 21 |
|
| 22 |
+
# In[4]:
|
| 23 |
|
| 24 |
|
| 25 |
# Load environment variables in a file called .env
|
|
|
|
| 46 |
print("Google API Key not set")
|
| 47 |
|
| 48 |
|
| 49 |
+
# In[5]:
|
| 50 |
|
| 51 |
|
| 52 |
# Connect to OpenAI, Anthropic and Google
|
|
|
|
| 61 |
GOOGLE_MODEL = "gemini-2.0-flash"
|
| 62 |
|
| 63 |
|
| 64 |
+
# In[6]:
|
| 65 |
|
| 66 |
|
| 67 |
system_message = "You are called \"EventAI\", a virtual assistant for an Elementary school called Eagle Elementary School. You can help users by giving \
|
|
|
|
| 73 |
list the questions and respond"
|
| 74 |
|
| 75 |
|
| 76 |
+
# In[7]:
|
| 77 |
|
| 78 |
|
| 79 |
# Some imports for handling images
|
|
|
|
| 83 |
from PIL import Image
|
| 84 |
|
| 85 |
|
| 86 |
+
# In[8]:
|
| 87 |
|
| 88 |
|
| 89 |
def artist(event_text):
|
|
|
|
| 99 |
return Image.open(BytesIO(image_data))
|
| 100 |
|
| 101 |
|
| 102 |
+
# In[34]:
|
| 103 |
|
| 104 |
|
| 105 |
import base64
|
|
|
|
| 115 |
|
| 116 |
audio_stream = BytesIO(response.content)
|
| 117 |
output_filename = "output_audio.mp3"
|
| 118 |
+
|
| 119 |
with open(output_filename, "wb") as f:
|
| 120 |
f.write(audio_stream.read())
|
| 121 |
+
return output_filename
|
| 122 |
+
#Commented below just for Huggingface deployment
|
| 123 |
+
# # Play the generated audio
|
| 124 |
+
# display(Audio(output_filename, autoplay=True))
|
| 125 |
|
|
|
|
|
|
|
| 126 |
|
| 127 |
+
# In[10]:
|
|
|
|
| 128 |
|
| 129 |
|
| 130 |
school_events = [
|
|
|
|
| 180 |
]
|
| 181 |
|
| 182 |
|
| 183 |
+
# In[11]:
|
| 184 |
|
| 185 |
|
| 186 |
def get_event_details(query):
|
|
|
|
| 202 |
#
|
| 203 |
# Well, kinda.
|
| 204 |
|
| 205 |
+
# In[12]:
|
| 206 |
|
| 207 |
|
| 208 |
# for claude
|
|
|
|
| 225 |
]
|
| 226 |
|
| 227 |
|
| 228 |
+
# In[13]:
|
| 229 |
|
| 230 |
|
| 231 |
# For GPT
|
|
|
|
| 247 |
}
|
| 248 |
|
| 249 |
|
| 250 |
+
# In[14]:
|
| 251 |
|
| 252 |
|
| 253 |
# And this is included in a list of tools:
|
| 254 |
tools_gpt = [{"type": "function", "function": events_function_gpt}]
|
| 255 |
|
| 256 |
|
| 257 |
+
# In[15]:
|
| 258 |
|
| 259 |
|
| 260 |
#Gemini function declaration structure
|
|
|
|
| 289 |
]
|
| 290 |
|
| 291 |
|
| 292 |
+
# In[26]:
|
| 293 |
|
| 294 |
|
| 295 |
def chat_claude(history):
|
|
|
|
| 354 |
for text in stream.text_stream:
|
| 355 |
result += text or ""
|
| 356 |
yield result, None
|
| 357 |
+
#talker(result)
|
| 358 |
#image= artist(tool_input.get('event_text'))
|
| 359 |
yield result, image
|
| 360 |
else:
|
|
|
|
| 363 |
for i in range(0, len(response), chunk_size):
|
| 364 |
yield response[:i + chunk_size], None
|
| 365 |
time.sleep(0.05) #Simulate streaming delay
|
| 366 |
+
#talker(response)
|
| 367 |
#image= artist(tool_input.get('event_text'))
|
| 368 |
yield response, None
|
| 369 |
except Exception as e:
|
|
|
|
| 373 |
|
| 374 |
|
| 375 |
|
| 376 |
+
# In[27]:
|
| 377 |
|
| 378 |
|
| 379 |
def chat_gpt(history):
|
|
|
|
| 405 |
for chunk in stream:
|
| 406 |
result += chunk.choices[0].delta.content or ""
|
| 407 |
yield result, None
|
| 408 |
+
#talker(result)
|
| 409 |
yield result, image
|
| 410 |
else:
|
| 411 |
reply = response.choices[0].message.content
|
|
|
|
| 413 |
for i in range(0, len(reply), chunk_size):
|
| 414 |
yield reply[:i + chunk_size], None
|
| 415 |
time.sleep(0.05)
|
| 416 |
+
#talker(reply)
|
| 417 |
#image= artist("No such event")
|
| 418 |
yield reply, None
|
| 419 |
except Exception as e:
|
|
|
|
| 422 |
yield error_message, None
|
| 423 |
|
| 424 |
|
| 425 |
+
# In[28]:
|
| 426 |
|
| 427 |
|
| 428 |
def chat_gemini(history):
|
| 429 |
+
print(f"\nhistory is {history}\n")
|
| 430 |
history_gemini = [{'role': m['role'], 'parts': [{'text': m['content']}]} if 'content' in m #if content exists, change it to parts format
|
| 431 |
else {'role': m['role'], 'parts': m['parts']} if 'parts' in m #else if parts exists, just copy it as it is
|
| 432 |
else {'role': m['role']} for m in history] #else neither content nor parts exists, copy only the role ignoring all other keys like metadata, options etc
|
|
|
|
| 465 |
result += chunk.candidates[0].content.parts[0].text or ""
|
| 466 |
#print(f"REsult is \n{result}\n")
|
| 467 |
yield result, None
|
| 468 |
+
#talker(result)
|
| 469 |
yield result, image
|
| 470 |
#print(f"REsult is \n{result}\n")
|
| 471 |
else:
|
|
|
|
| 474 |
for i in range(0, len(reply), chunk_size):
|
| 475 |
yield reply[:i + chunk_size], None
|
| 476 |
time.sleep(0.05)
|
| 477 |
+
#talker(reply)
|
| 478 |
#image= artist("No such event")
|
| 479 |
yield reply, None
|
| 480 |
|
| 481 |
except Exception as e:
|
| 482 |
error_message = "Apologies, my server is acting weird. Please try again later."
|
| 483 |
print(e)
|
| 484 |
+
yield error_message, None
|
|
|
|
|
|
|
|
|
|
| 485 |
|
| 486 |
|
| 487 |
|
| 488 |
+
# In[29]:
|
| 489 |
|
| 490 |
|
| 491 |
def call_and_process_model_responses(fn_name, chatbot):#, response, image):
|
|
|
|
| 501 |
|
| 502 |
|
| 503 |
|
| 504 |
+
# In[30]:
|
| 505 |
|
| 506 |
|
| 507 |
def handle_tool_call(event_text):
|
|
|
|
| 517 |
|
| 518 |
|
| 519 |
|
| 520 |
+
# In[31]:
|
| 521 |
|
| 522 |
|
| 523 |
def process_chosen_model(chatbot, model):
|
|
|
|
| 534 |
|
| 535 |
|
| 536 |
|
| 537 |
+
# In[35]:
|
| 538 |
|
| 539 |
|
| 540 |
# More involved Gradio code as we're not using the preset Chat interface!
|
|
|
|
| 578 |
|
| 579 |
entry.submit(do_entry, inputs=[entry, chatbot], outputs=[entry, chatbot]).then(
|
| 580 |
process_chosen_model, inputs=[chatbot, model], outputs=[chatbot, image_output]
|
| 581 |
+
).then(#added this specifically for Hugging face spaces deployment
|
| 582 |
+
lambda chat: talker(chat[-1]["content"]), inputs=[chatbot], outputs=gr.Audio()
|
| 583 |
)
|
| 584 |
+
|
| 585 |
clear.click(lambda: None, inputs=None, outputs=chatbot, queue=False)
|
| 586 |
|
| 587 |
+
|
| 588 |
+
# In[36]:
|
| 589 |
+
|
| 590 |
+
|
| 591 |
ui.launch(inbrowser=True)
|
| 592 |
|
| 593 |
|