Reminders / app.py
Josedcape's picture
Update app.py
eb48279 verified
import os
import time
import groq
from google.cloud import texttospeech_v1 as texttospeech
import streamlit as st
from dotenv import load_dotenv
import speech_recognition as sr
from datetime import datetime, timedelta
from streamlit_autorefresh import st_autorefresh
# Configurar la p谩gina de Streamlit
st.set_page_config(page_title="Galatea Asistente - OMARDENT", layout="wide")
# Estilo CSS para el fondo
st.markdown(
"""
<style>
.reportview-container {
background: radial-gradient(circle, rgba(209,238,174,1) 0%, rgba(11,135,128,1) 90%);
}
</style>
""",
unsafe_allow_html=True
)
# Agregar el logo
st.image("Logo icon.jpg", use_column_width=True) # Aseg煤rate de que el archivo icon.jpg est茅 en la misma carpeta
# Cargar las claves API desde el archivo .env
load_dotenv()
groq_api_key = os.getenv("GROQ_API_KEY")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "credentials/botidinamix-g.json"
# Verificar que la clave API de Groq est谩 configurada
if not groq_api_key:
st.error("No API key provided for Groq. Please set your API key in the .env file.")
else:
# Inicializar el cliente de Groq
client_groq = groq.Groq(api_key=groq_api_key)
# Funci贸n para obtener respuesta de Groq y generar audio con Google TTS
def obtener_respuesta_groq(pregunta, contexto="", modelo="llama3-8b-8192", temperatura=0.5):
if not pregunta:
st.error("La pregunta no puede estar vac铆a.")
return "Lo siento, la pregunta no puede estar vac铆a."
try:
with st.spinner('Evaluando su respuesta...'):
# Hacer la llamada a la API de Groq con el rol de Galatea
contexto = "Act煤as como Galatea, la asistente virtual de la cl铆nica odontol贸gica Omardent. Tu funci贸n es recordar citas y eventos de forma clara y profesional."
response = client_groq.chat.completions.create(
messages=[
{"role": "system", "content": contexto},
{"role": "user", "content": pregunta}
],
model=modelo
)
# Acceder al contenido de la respuesta de Groq
respuesta = response.choices[0].message.content.strip()
# Configurar la solicitud de s铆ntesis de voz (Google TTS)
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(text=respuesta)
voice = texttospeech.VoiceSelectionParams(
language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
# Realizar la solicitud de s铆ntesis de voz
response_audio = client.synthesize_speech(
input=input_text, voice=voice, audio_config=audio_config
)
# Guardar el archivo de audio temporalmente
audio_file_path = f'tmp_respuesta_{int(time.time())}.mp3'
with open(audio_file_path, 'wb') as audio_file:
audio_file.write(response_audio.audio_content)
# Devolver la respuesta y la ruta del archivo de audio
return respuesta, audio_file_path
except Exception as e:
st.error(f"Error al generar la respuesta y el audio: {e}")
return "Lo siento, ocurri贸 un error al procesar tu solicitud.", None
# Funci贸n para manejar el chat del asistente
def mostrar_galatea_asistente():
st.title("馃Ψ Galatea - Asistente Virtual OMARDENT")
# Inicializa el historial del chat y el temporizador
if 'mensajes_chat' not in st.session_state:
st.session_state['mensajes_chat'] = []
if 'respuesta_programada' not in st.session_state:
st.session_state['respuesta_programada'] = None
# Mostrar los mensajes del chat
for mensaje in st.session_state['mensajes_chat']:
clase = "user" if mensaje["role"] == "user" else "assistant"
st.markdown(f'<div class="chat-message {clase}">{mensaje["content"]}</div>', unsafe_allow_html=True)
# Entrada de texto para la pregunta del usuario
pregunta_usuario = st.text_input("Escribe tu pregunta aqu铆:")
# Selector de intervalo de tiempo
intervalo = st.selectbox("Selecciona el intervalo de tiempo (minutos)", [1, 2, 5, 10, 15, 30, 60])
# Grabar y transcribir audio
if st.button("Grabar y Transcribir Audio"):
recognizer = sr.Recognizer()
with sr.Microphone() as source:
st.info("Grabando...")
audio = recognizer.listen(source, timeout=5)
st.info("Grabaci贸n completa")
try:
text = recognizer.recognize_google(audio, language="es-ES")
pregunta_usuario = text # Usar la transcripci贸n como la pregunta
except sr.UnknownValueError:
st.error("No se pudo entender el audio")
except sr.RequestError:
st.error("Error al solicitar el servicio de reconocimiento de voz")
# Programar la pregunta para ser respondida despu茅s del intervalo de tiempo seleccionado
if st.button("Programar Respuesta"):
if pregunta_usuario:
# Guardar la pregunta en el historial
st.session_state['mensajes_chat'].append({"role": "user", "content": pregunta_usuario})
# Calcular el tiempo en segundos
tiempo_en_segundos = intervalo * 60
tiempo_ejecucion = datetime.now() + timedelta(minutes=intervalo)
st.success(f"La respuesta se generar谩 a las {tiempo_ejecucion.strftime('%H:%M:%S')}")
# Guardar la informaci贸n de la respuesta programada
st.session_state['respuesta_programada'] = {
'pregunta': pregunta_usuario,
'tiempo_ejecucion': tiempo_ejecucion,
'tiempo_en_segundos': tiempo_en_segundos,
'audio_file_path': None,
'notificacion_reproducida': False # Para saber si se ha reproducido la notificaci贸n
}
# Actualizar la interfaz cada segundo para verificar si el tiempo ha pasado y mostrar el contador
st_autorefresh(interval=1000, key="data_refresh")
# Verificar si hay una respuesta programada que deba ejecutarse
if 'respuesta_programada' in st.session_state and st.session_state['respuesta_programada']:
respuesta_programada = st.session_state['respuesta_programada']
# Mostrar el contador del tiempo restante
tiempo_restante = respuesta_programada['tiempo_ejecucion'] - datetime.now()
if tiempo_restante.total_seconds() > 0:
minutos, segundos = divmod(int(tiempo_restante.total_seconds()), 60)
horas, minutos = divmod(minutos, 60)
tiempo_restante_str = f"{horas}h {minutos}m {segundos}s" if horas > 0 else f"{minutos}m {segundos}s"
st.info(f"Tiempo restante: {tiempo_restante_str}")
if st.session_state['respuesta_programada']['notificacion_reproducida'] and st.session_state['respuesta_programada']['audio_file_path'] is None:
respuesta, audio_file_path = obtener_respuesta_groq(respuesta_programada['pregunta'])
# Guardar la respuesta y el audio en el estado
st.session_state['mensajes_chat'].append({"role": "assistant", "content": respuesta})
st.session_state['respuesta_programada']['audio_file_path'] = audio_file_path
# Reproducir el audio si ya fue generado
if st.session_state['respuesta_programada']['audio_file_path']:
audio_file_path = st.session_state['respuesta_programada']['audio_file_path']
with open(audio_file_path, "rb") as audio_file:
st.audio(audio_file.read(), format="audio/mp3")
# Funci贸n principal
def main():
mostrar_galatea_asistente()
if __name__ == "__main__":
main()