Spaces:
Paused
Paused
# Standard libraries | |
import base64 | |
import io | |
import json | |
import os | |
import re | |
import tempfile | |
import time | |
from os import getenv | |
from typing import Any | |
from typing import Dict | |
from typing import IO | |
from typing import List | |
from typing import Optional | |
from typing import Tuple | |
from typing import Union | |
from io import BytesIO | |
from copy import deepcopy | |
# Third-party libraries | |
import requests | |
import streamlit as st | |
#from audiorecorder import audiorecorder | |
from openai import OpenAI | |
from pydub import AudioSegment | |
import warnings | |
# Ignore DeprecationWarning | |
warnings.filterwarnings("ignore", category=DeprecationWarning) | |
from var_app import __version__ | |
from core.files import load_ui_language | |
from core.files import read_file | |
from core.text_to_speech import openai_tts | |
from core.DetectLanguage import detect_language | |
from core.speech_to_text import huggingface_endpoints_stt | |
from core.speech_to_text import transcribe_audio | |
from core.audio_files import concatenate_audio_files | |
from core.audio_files import split_audio | |
# Au début du fichier, après les imports | |
st.set_page_config( | |
page_title=f"DEMORRHA - (v{__version__})", | |
page_icon="👹", | |
layout="wide", | |
initial_sidebar_state="collapsed" | |
) | |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
def get_translation(key: str) -> str: | |
""" | |
Obtient la traduction pour une clé donnée basée sur la langue d'interface sélectionnée. | |
""" | |
lang = st.session_state.get('interface_language', 'English') | |
return translations.get(lang, {}).get(key, key) | |
# Dictionary to store translations | |
translations = load_ui_language() | |
def process_tts_message(text_response: str) -> Tuple[Optional[bytes], Optional[float]]: | |
try: | |
tts_output_ = openai_tts( | |
tts_voice=st.session_state.tts_voice, | |
tts_model="tts-1", | |
response_format="mp3", | |
speed=1.0 | |
).text_to_speech(text_response) | |
return tts_output_["data_bytes"], tts_output_["audio_duration"] | |
except Exception as e: | |
st.error(f"Une erreur s'est produite lors de la conversion texte-parole : {e}") | |
return None, None | |
def process_message( | |
message: str, | |
operation_prompt_: Optional[str] = "", | |
system_prompt_: Optional[str] = "" | |
): | |
""" | |
Traite les messages des utilisateurs et génère une réponse. | |
Args: | |
message (str): Le message d'entrée de l'utilisateur. | |
operation_prompt (str, optional): Prompt supplémentaire pour l'opération. Par défaut "". | |
tts_enabled (bool, optional): Si la synthèse vocale est activée. Par défaut False. | |
""" | |
payload_content = f'{operation_prompt_} :\n"""\n{message}\n"""' | |
st.session_state.messages = [ | |
{"role": "system", "content": system_prompt_}, | |
{"role": "user", "content": payload_content} | |
] | |
st.session_state["full_response"] = "" | |
try: | |
for response in client.chat.completions.create( | |
model="gpt-4o-mini", | |
messages=st.session_state.messages, | |
stream=True, | |
temperature=0.1): | |
st.session_state.full_response += (response.choices[0].delta.content or "") | |
yield st.session_state.full_response + "▌" | |
# Utiliser regex pour supprimer les trois premiers et derniers guillemets doubles | |
st.session_state.full_response = re.sub(r'^"{3}|"{3}$', '', st.session_state.full_response.strip()) | |
st.session_state.messages = [] | |
return st.session_state.full_response | |
except Exception as e: | |
st.error(f"Une erreur s'est produite lors de la génération de la réponse : {e}") | |
return "" | |
class GlobalSystemPrompts: | |
"""Class to store global system prompts.""" | |
def linguascribe(): | |
""" | |
Retrieve the system prompt for the Linguascribe feature. | |
Returns: | |
str: The system prompt for Linguascribe. | |
""" | |
try: | |
system_prompt = read_file('linguascribe.prompt') | |
return system_prompt | |
except FileNotFoundError: | |
print("Le fichier 'linguascribe.prompt' n'a pas été trouvé.") | |
return "" | |
except IOError as e: | |
print(f"Erreur lors de la lecture du fichier 'linguascribe.prompt': {e}") | |
return "" | |
# Function to configure the translation mode | |
def set_translation_mode(from_lang: str, dest_lang: str) -> Tuple[str, str]: | |
""" | |
Configure les prompts globaux pour le mode de traduction. | |
Args: | |
from_lang (str): La langue source. | |
dest_lang (str): La langue de destination. | |
Returns: | |
Tuple[str, str]: Un tuple contenant le prompt système et le prompt d'opération. | |
""" | |
system_prompt_ = GlobalSystemPrompts.linguascribe() | |
operation_prompt_ = f"Translate({from_lang} to {dest_lang})" | |
return system_prompt_, operation_prompt_ | |
# List of languages supported by the application | |
SUPPORTED_LANGUAGES = [ | |
"Afrikaans", "Arabic", "Armenian", "Azerbaijani", "Belarusian", "Bosnian", | |
"Bulgarian", "Catalan", "Chinese", "Croatian", "Czech", "Danish", "Dutch", | |
"English", "Estonian", "Finnish", "French", "Galician", "German", "Greek", | |
"Hebrew", "Hindi", "Hungarian", "Icelandic", "Indonesian", "Italian", | |
"Japanese", "Kannada", "Kazakh", "Korean", "Latvian", "Lithuanian", | |
"Macedonian", "Malay", "Marathi", "Maori", "Nepali", "Norwegian", "Persian", | |
"Polish", "Portuguese", "Romanian", "Russian", "Serbian", "Slovak", | |
"Slovenian", "Spanish", "Swahili", "Swedish", "Tagalog", "Tamil", "Thai", | |
"Turkish", "Ukrainian", "Urdu", "Vietnamese", "Welsh" | |
] | |
LANGUAGES_EMOJI = { | |
"Afrikaans": "🇿🇦", "Arabic": "🇸🇦", "Armenian": "🇦🇲", "Azerbaijani": "🇦🇿", "Belarusian": "🇧🇾", | |
"Bosnian": "🇧🇦", "Bulgarian": "🇧🇬", "Catalan": "🇪🇸", "Chinese": "🇨🇳", "Croatian": "🇭🇷", | |
"Czech": "🇨🇿", "Danish": "🇩🇰", "Dutch": "🇳🇱", "English": "🇬🇧", "Estonian": "🇪🇪", | |
"Finnish": "🇫🇮", "French": "🇫🇷", "Galician": "🇪🇸", "German": "🇩🇪", "Greek": "🇬🇷", | |
"Hebrew": "🇮🇱", "Hindi": "🇮🇳", "Hungarian": "🇭🇺", "Icelandic": "🇮🇸", "Indonesian": "🇮🇩", | |
"Italian": "🇮🇹", "Japanese": "🇯🇵", "Kannada": "🇮🇳", "Kazakh": "🇰🇿", "Korean": "🇰🇷", | |
"Latvian": "🇱🇻", "Lithuanian": "🇱🇹", "Macedonian": "🇲🇰", "Malay": "🇲🇾", "Marathi": "🇮🇳", | |
"Maori": "🇳🇿", "Nepali": "🇳🇵", "Norwegian": "🇳🇴", "Persian": "🇮🇷", "Polish": "🇵🇱", | |
"Portuguese": "🇵🇹", "Romanian": "🇷🇴", "Russian": "🇷🇺", "Serbian": "🇷🇸", "Slovak": "🇸🇰", | |
"Slovenian": "🇸🇮", "Spanish": "🇪🇸", "Swahili": "🇰🇪", "Swedish": "🇸🇪", "Tagalog": "🇵🇭", | |
"Tamil": "🇮🇳", "Thai": "🇹🇭", "Turkish": "🇹🇷", "Ukrainian": "🇺🇦", "Urdu": "🇵🇰", | |
"Vietnamese": "🇻🇳", "Welsh": "🏴" | |
} | |
def convert_iso6391_to_language_name(language_code: str, | |
filter_mode=True) -> str: | |
""" | |
Convertit un code ISO 639-1 en nom de langue. | |
Args: | |
language_code (str): Le code ISO 639-1 de la langue. | |
Returns: | |
str: Le nom de la langue correspondant au code ISO 639-1, ou 'English' si non trouvé. | |
""" | |
# Dictionnaire associant les codes ISO 639-1 aux noms de langues | |
iso_to_language: Dict[str, str] = { | |
"af": "Afrikaans", "ar": "Arabic", "hy": "Armenian", "az": "Azerbaijani", | |
"be": "Belarusian", "bs": "Bosnian", "bg": "Bulgarian", "ca": "Catalan", | |
"zh": "Chinese", "hr": "Croatian", "cs": "Czech", "da": "Danish", | |
"nl": "Dutch", "en": "English", "et": "Estonian", "fi": "Finnish", | |
"fr": "French", "gl": "Galician", "de": "German", "el": "Greek", | |
"he": "Hebrew", "hi": "Hindi", "hu": "Hungarian", "is": "Icelandic", | |
"id": "Indonesian", "it": "Italian", "ja": "Japanese", "kn": "Kannada", | |
"kk": "Kazakh", "ko": "Korean", "lv": "Latvian", "lt": "Lithuanian", | |
"mk": "Macedonian", "ms": "Malay", "mr": "Marathi", "mi": "Maori", | |
"ne": "Nepali", "no": "Norwegian", "fa": "Persian", "pl": "Polish", | |
"pt": "Portuguese", "ro": "Romanian", "ru": "Russian", "sr": "Serbian", | |
"sk": "Slovak", "sl": "Slovenian", "es": "Spanish", "sw": "Swahili", | |
"sv": "Swedish", "tl": "Tagalog", "ta": "Tamil", "th": "Thai", | |
"tr": "Turkish", "uk": "Ukrainian", "ur": "Urdu", "vi": "Vietnamese", | |
"cy": "Welsh" | |
} | |
default_ = "English" | |
try: | |
# Retourner le nom de la langue correspondant au code ISO 639-1 | |
return iso_to_language[language_code] | |
except KeyError: | |
if f"{language_code}" in iso_to_language.values(): | |
return language_code | |
else: | |
# Gérer spécifiquement l'exception KeyError | |
print(f"Code de langue non trouvé : {language_code}") | |
return default_ | |
def convert_language_name_to_iso6391(language_data: Union[str, Dict[str, str]]) -> str: | |
""" | |
Convertit un nom de langue en son code ISO 639-1. | |
Args: | |
language_data (Union[str, Dict[str, str]]): Le nom de la langue ou un dictionnaire | |
contenant le nom de la langue. | |
Returns: | |
str: Le code ISO 639-1 pour la langue donnée, ou 'en' si non trouvé. | |
""" | |
# Dictionnaire associant les noms de langues aux codes ISO 639-1 | |
language_to_iso: Dict[str, str] = { | |
"Afrikaans": "af", "Arabic": "ar", "Armenian": "hy", "Azerbaijani": "az", | |
"Belarusian": "be", "Bosnian": "bs", "Bulgarian": "bg", "Catalan": "ca", | |
"Chinese": "zh", "Croatian": "hr", "Czech": "cs", "Danish": "da", | |
"Dutch": "nl", "English": "en", "Estonian": "et", "Finnish": "fi", | |
"French": "fr", "Galician": "gl", "German": "de", "Greek": "el", | |
"Hebrew": "he", "Hindi": "hi", "Hungarian": "hu", "Icelandic": "is", | |
"Indonesian": "id", "Italian": "it", "Japanese": "ja", "Kannada": "kn", | |
"Kazakh": "kk", "Korean": "ko", "Latvian": "lv", "Lithuanian": "lt", | |
"Macedonian": "mk", "Malay": "ms", "Marathi": "mr", "Maori": "mi", | |
"Nepali": "ne", "Norwegian": "no", "Persian": "fa", "Polish": "pl", | |
"Portuguese": "pt", "Romanian": "ro", "Russian": "ru", "Serbian": "sr", | |
"Slovak": "sk", "Slovenian": "sl", "Spanish": "es", "Swahili": "sw", | |
"Swedish": "sv", "Tagalog": "tl", "Tamil": "ta", "Thai": "th", | |
"Turkish": "tr", "Ukrainian": "uk", "Urdu": "ur", "Vietnamese": "vi", | |
"Welsh": "cy" | |
} | |
default_ = "en" | |
# Vérifier si language_data est un dictionnaire | |
if isinstance(language_data, dict): | |
language_name = language_data.get('language', '') | |
else: | |
language_name = language_data | |
try: | |
# Retourner le code ISO 639-1 correspondant au nom de la langue | |
return language_to_iso[language_name] | |
except KeyError: | |
if f"{language_name}" in language_to_iso.values(): | |
return language_name | |
else: | |
# Gérer spécifiquement l'exception KeyError | |
print(f"Langue non trouvée : {language_name}") | |
return default_ | |
def init_process_mode( | |
from_lang: str, | |
to_lang: str, | |
process_mode: Optional[str|list] = "translator" | |
) -> Tuple[str, str]: | |
""" | |
Initialise le mode de traitement pour la traduction si nécessaire. | |
Returns: | |
Tuple[str, str]: Un tuple contenant le prompt système et le prompt d'opération. | |
""" | |
# from (e.g.: st.session_state.language_detected) | |
# dest (e.g.: st.session_state.target_language) | |
if "translator" in process_mode: | |
system_prompt, operation_prompt = set_translation_mode( | |
from_lang=f"{from_lang}", | |
dest_lang=f"{to_lang}" | |
) | |
return system_prompt, operation_prompt | |
return "", "" | |
def tts_settings(name__tts_voice, | |
state__tts_with_text, | |
state__tts_with_audio, | |
state__autoplay_tts): | |
with st.expander(f"{get_translation('parametres_tts')}", | |
expanded=True, | |
icon="🔊"): | |
set__tts_voice = st.selectbox( | |
get_translation("choix_voix_tts"), | |
options=["alloy", "echo", "fable", "onyx", "nova", "shimmer"], | |
index=list(["alloy", "echo", "fable", "onyx", "nova", "shimmer"]).index(name__tts_voice) | |
) | |
set__tts_with_text = st.checkbox( | |
get_translation("activer_tts_texte"), | |
value=state__tts_with_text | |
) | |
set__tts_with_audio = st.checkbox( | |
get_translation("activer_tts_audio"), | |
value=state__tts_with_audio | |
) | |
set__autoplay_tts = st.checkbox( | |
get_translation("lecture_auto_tts"), | |
value=state__autoplay_tts | |
) | |
if st.button("Submit"): | |
st.session_state.autoplay_tts = set__autoplay_tts | |
st.session_state.enable_tts_for_input_from_audio_record = set__tts_with_audio | |
st.session_state.enable_tts_for_input_from_text_field = set__tts_with_text | |
st.session_state.tts_voice = set__tts_voice | |
#st.session_state. | |
st.rerun() | |
def recorder_released(): | |
if "rec_widget" in st.session_state: | |
if st.session_state.rec_widget: | |
audio_recorded = True | |
else: | |
audio_recorded = False | |
if audio_recorded: | |
audio = AudioSegment.from_wav(io.BytesIO(st.session_state.rec_widget.getvalue())) | |
st.write(f"Frame rate: {audio.frame_rate}, Frame width: {audio.frame_width}, Duration: {audio.duration_seconds} seconds") | |
if not (st.session_state.language_detected): | |
# 1. Verifie si audio.duration_seconds est superieur a 600 secondes (10 minutes) | |
if audio.duration_seconds > 600: | |
# PyDub handles time in milliseconds | |
ten_minutes = 10 * 60 * 1000 | |
first_ten_minutes_audio = audio[:ten_minutes] | |
else: | |
# less than ten minutes ... nervermind, the name of this variable is | |
first_ten_minutes_audio = deepcopy(audio) | |
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp_extract: | |
first_ten_minutes_audio.export(tmp_extract, format="mp3") | |
tmp_extract.close() | |
# il faut transcrire sans specifier l'argument language dans la fonction transcribe_audio | |
# ensuite on pourra utiliser la fonction detect_language pour detecter la langue du texte transcrit | |
# Transcrire les 10 premiers minutes audio en texte | |
st.session_state.language_detected = detect_language( | |
input_text = transcribe_audio(tmp_extract), | |
temperature = 0.2, | |
context_window = 512, | |
model = "gpt-4o-mini" | |
) | |
first_ten_minutes_audio = AudioSegment.empty() | |
st.markdown( | |
f"- {get_translation('langue_detectee')}".format( | |
f"{convert_iso6391_to_language_name(st.session_state.language_detected)}" | |
) | |
) | |
# ############################################################## | |
try: | |
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp_file: | |
audio.export(tmp_file, format="mp3") | |
tmp_file.close() | |
# Transcrire l'audio en texte | |
st.session_state.transcription = transcribe_audio( | |
tmp_file, | |
language=st.session_state.language_detected | |
) | |
audio = AudioSegment.empty() | |
st.markdown( | |
f"🎤 {get_translation('transcription_audio')}".format( | |
f"{st.session_state.transcription}" | |
) | |
) | |
st.session_state.audio_list = [] | |
for cursor_selected_lang in st.session_state.selected_languages: | |
st.session_state.target_language = cursor_selected_lang["iso-639-1"] | |
st.session_state.full_response = "" | |
# Initialisation du mode de traitement pour la langue cible actuelle | |
st.session_state.system_prompt, st.session_state.operation_prompt = init_process_mode(from_lang= | |
( | |
st.session_state.language_detected if "language_detected" in st.session_state.language_detected else convert_language_name_to_iso6391( | |
st.session_state.interface_language | |
) | |
), | |
to_lang=st.session_state.target_language | |
) | |
with st.chat_message("assistant", avatar="👻"): | |
message_placeholder = st.empty() | |
st.session_state.response_generator = process_message( | |
st.session_state.transcription, | |
st.session_state.operation_prompt, | |
st.session_state.system_prompt | |
) | |
for response_chunk in st.session_state.response_generator: | |
message_placeholder.markdown(response_chunk) | |
st.session_state.end_response = st.session_state.response_generator.close() | |
if st.session_state.full_response != "": | |
message_placeholder.markdown(st.session_state.full_response) | |
if st.session_state.enable_tts_for_input_from_audio_record: | |
st.session_state.tts_audio, st.session_state.tts_duration = process_tts_message(st.session_state.full_response) | |
if st.session_state.tts_audio: | |
st.session_state.audio_list.append( | |
( st.session_state.tts_audio, | |
st.session_state.tts_duration ) | |
) | |
else: | |
pass | |
if st.session_state.audio_list: | |
st.session_state.final_audio = concatenate_audio_files(st.session_state.audio_list) | |
with st.container(border=True): | |
# Générer un nom de fichier unique | |
st.session_state.timestamp = time.strftime("%Y%m%d-%H%M%S") | |
st.session_state.langues = "_".join([lang["iso-639-1"] for lang in st.session_state.selected_languages]) | |
st.session_state.nom_fichier = f"reponse_audio_{st.session_state.langues}_{st.session_state.timestamp}.mp3" | |
st.audio(st.session_state.final_audio, | |
format="audio/mp3", | |
autoplay=st.session_state.autoplay_tts) | |
st.download_button( | |
label=f"📥 {get_translation('telecharger_audio')}", | |
data=st.session_state.final_audio, | |
file_name=st.session_state.nom_fichier, | |
mime="audio/mp3", | |
use_container_width=True, | |
type="primary", | |
key=f"download_button_{st.session_state.langues}_{st.session_state.timestamp}", | |
) | |
except Exception as e: | |
st.error(f"[AUDIO] - Erreur lors de l'exportation de l'audio : {str(e)}") | |
#finally: | |
# clear_inputs_garbages() | |
# if 'tmp_file' in locals(): | |
# os.unlink(tmp_file.name) | |
##st.session_state.rec_widget.close() | |
#if "rec_widget" in st.session_state: | |
# list_dir_obj = dir(st.session_state.rec_widget) | |
# for itl in list_dir_obj: | |
# if "__" not in itl: | |
# st.write(f"***{itl}*** :\n{getattr(st.session_state.rec_widget, itl).__doc__}") | |
def main_page(): | |
"""Page principale de l'application.""" | |
# Initialisation des variables d'état de session | |
if "ui_loaded" not in st.session_state: | |
st.session_state["ui_loaded"] = False | |
if "language_detected" not in st.session_state: | |
st.session_state["language_detected"] = None | |
if "process_mode" not in st.session_state: | |
st.session_state["process_mode"] = "translation" | |
if "target_language" not in st.session_state: | |
st.session_state.target_language = "en" | |
if "selected_languages" not in st.session_state: | |
st.session_state.selected_languages = [ | |
{"language": "English", "iso-639-1": "en"} | |
] | |
if "interface_language_select" not in st.session_state: | |
st.session_state.interface_language_select = "English" # Langue par défaut | |
if "enable_tts_for_input_from_audio_record" not in st.session_state: | |
st.session_state["enable_tts_for_input_from_audio_record"] = False | |
if "autoplay_tts" not in st.session_state: | |
st.session_state["autoplay_tts"] = False | |
if "enable_tts_for_input_from_text_field" not in st.session_state: | |
st.session_state["enable_tts_for_input_from_text_field"] = False | |
if "tts_voice" not in st.session_state: | |
st.session_state["tts_voice"] = "onyx" | |
# Initialisation de l'historique des messages avec le prompt système | |
if "messages" not in st.session_state: | |
st.session_state.messages = [] | |
def on_languages_change() -> None: | |
#clear_inputs_garbages() | |
"""Fonction de rappel pour le changement de langue(s) de destination.""" | |
selected_language_names: List[str] = st.session_state.language_selector | |
st.session_state.selected_languages = [ | |
{"language": lang, "iso-639-1": convert_language_name_to_iso6391(lang)} | |
for lang in selected_language_names | |
] | |
# Configuration de la barre latérale | |
with st.sidebar: | |
st.logo("img/logo_2.png", icon_image="img/logo_2.png") | |
st.header(get_translation("sidebar_titre")) | |
st.write(f"#### Settings") | |
if st.button(f"Text-To-Speech"): | |
tts_settings( | |
name__tts_voice = st.session_state.tts_voice, | |
state__tts_with_text = st.session_state.enable_tts_for_input_from_text_field, | |
state__tts_with_audio = st.session_state.enable_tts_for_input_from_audio_record, | |
state__autoplay_tts = st.session_state.autoplay_tts | |
) | |
with st.expander(f"{get_translation('a_propos')}", | |
expanded=False, | |
icon="ℹ️"): | |
st.subheader(f"version: {__version__}") | |
st.info(get_translation("info_app")) | |
with st.expander(f"{get_translation('selection_langue')}", | |
expanded=True, | |
icon="🌐"): | |
# Conteneur pour la sélection de langue | |
# Sélection multiple des langues de destination | |
st.multiselect( | |
label=get_translation("langues_destination"), | |
placeholder=get_translation("placeholder_langues"), | |
options=SUPPORTED_LANGUAGES, | |
default=["English"], | |
key="language_selector", | |
max_selections=4, | |
on_change=on_languages_change, | |
format_func=lambda lang: f"{LANGUAGES_EMOJI.get(lang, '')} {lang}" | |
) | |
with st.container(border=True): | |
# Interface utilisateur pour le chat textuel | |
st.session_state.user_input = st.chat_input( | |
get_translation("entrez_message") | |
) | |
st.experimental_audio_input("Record a voice message",on_change=recorder_released, key="rec_widget") | |
if st.session_state.user_input: | |
# Réinitialiser l'état précédent | |
st.session_state.full_response = "" | |
with st.chat_message("user", avatar="👤"): | |
st.markdown(st.session_state.user_input) | |
# Traitement du message texte de l'utilisateur | |
if st.session_state.language_detected is None: | |
st.session_state.language_detected = detect_language( | |
input_text = st.session_state.user_input, | |
temperature = 0.01, | |
context_window = 512, | |
model="gpt-4o" | |
) | |
st.session_state.audio_list = [] | |
for cursor_selected_lang in st.session_state.selected_languages: | |
st.session_state.target_language = cursor_selected_lang["iso-639-1"] | |
target_language_name = cursor_selected_lang["language"] | |
# Réinitialiser les messages avant de traiter une nouvelle entrée | |
st.session_state.messages = [] | |
st.session_state.full_response = "" | |
# Initialisation du mode de traitement pour la langue cible actuelle | |
st.session_state.system_prompt, st.session_state.operation_prompt = init_process_mode(from_lang= | |
( | |
st.session_state.language_detected if "language_detected" in st.session_state.language_detected else convert_language_name_to_iso6391( | |
st.session_state.interface_language | |
) | |
), | |
to_lang=st.session_state.target_language | |
) | |
# display error with st.error ; if (st.session_state.system_prompt, st.session_state.operation_prompt) is "", "" or None, None, and raise error | |
if (not st.session_state.system_prompt) or (not st.session_state.operation_prompt): | |
st.error("Erreur : Les prompts système ou d'opération sont vides.") | |
raise ValueError("Les prompts système ou d'opération ne peuvent pas être vides.") | |
with st.status(f'({target_language_name}) - {get_translation("traduction_en_cours")}', expanded=True) as response_status: | |
with st.chat_message("assistant", avatar="👻"): | |
message_placeholder = st.empty() | |
st.session_state.response_generator = process_message( | |
st.session_state.user_input, | |
st.session_state.operation_prompt, | |
st.session_state.system_prompt | |
) | |
response_status.update(label=f'({target_language_name}) - {get_translation("traduction_en_cours")}', state="running", expanded=True) | |
for response_chunk in st.session_state.response_generator: | |
message_placeholder.markdown(response_chunk) | |
st.session_state.end_response = st.session_state.response_generator.close() # Obtenir la réponse complète à la fin | |
if st.session_state.full_response != "": | |
message_placeholder.markdown(st.session_state.full_response) | |
if st.session_state.enable_tts_for_input_from_text_field: | |
response_status.update(label=f'({target_language_name}) - {get_translation("traduction_terminee")} ; {get_translation("synthese_vocale_en_cours")}', state="running", expanded=False) | |
st.session_state.tts_audio, st.session_state.tts_duration = process_tts_message(st.session_state.full_response) | |
del st.session_state.full_response | |
if st.session_state.tts_audio: | |
st.audio(base64.b64decode(st.session_state.tts_audio.encode()), format="audio/mp3", autoplay=False) | |
st.session_state.audio_list.append((base64.b64decode(st.session_state.tts_audio.encode()), st.session_state.tts_duration)) | |
response_status.update(label=f'({target_language_name}) - {get_translation("traduction_terminee")} ; {get_translation("synthese_vocale_terminee")}', state="complete", expanded=False) | |
else: | |
response_status.update(label=f'({target_language_name}) - {get_translation("erreur_synthese_vocale")}', state="error", expanded=False) | |
else: | |
response_status.update(label=f'({target_language_name}) - {get_translation("traduction_terminee")}', state="complete", expanded=False) | |
else: | |
response_status.update(label=f'({target_language_name}) - {get_translation("erreur_traduction")}', state="error", expanded=False) | |
if st.session_state.audio_list: | |
with st.status(f"{get_translation('concatenation_audio_en_cours')}", expanded=False) as audio_status: | |
audio_status.update(label=f"{get_translation('concatenation_audio_en_cours')}", state="running", expanded=False) | |
try: | |
st.session_state.final_audio = concatenate_audio_files(st.session_state.audio_list) | |
with st.container(border=True): | |
# Générer un nom de fichier unique | |
st.session_state.timestamp = time.strftime("%Y%m%d-%H%M%S") | |
st.session_state.langues = "_".join([lang["iso-639-1"] for lang in st.session_state.selected_languages]) | |
st.session_state.nom_fichier = f"reponse_audio_{st.session_state.langues}_{st.session_state.timestamp}.mp3" | |
st.audio(st.session_state.final_audio, format="audio/mp3", autoplay=st.session_state.autoplay_tts) | |
st.download_button( | |
label=f"📥 {get_translation('telecharger_audio')}", | |
data=st.session_state.final_audio, | |
file_name=st.session_state.nom_fichier, | |
mime="audio/mp3", | |
use_container_width=True, | |
type="primary", | |
key=f"download_button_{st.session_state.langues}_{st.session_state.timestamp}", | |
) | |
audio_status.update(label=f"{get_translation('concatenation_audio_terminee')}", state="complete", expanded=True) | |
except Exception as e: | |
st.error(f"{get_translation('erreur_concatenation_audio')} : {str(e)}") | |
audio_status.update(label=f"{get_translation('erreur_concatenation_audio')} : {str(e)}", state="error", expanded=True) | |
def clear_inputs_garbages(sessions_state_list: Optional[list] = | |
[ 'transcription', 'operation_prompt', 'system_prompt', | |
'audio_list', 'full_response', 'tts_audio', | |
'tts_duration', 'timestamp', 'langues', | |
'nom_fichier', 'final_audio', 'response_generator', | |
'end_response', 'messages', 'audio', 'user_input' ] | |
): | |
def delete_session_state_var(var_name: str): | |
if f"{var_name}" in st.session_state: | |
del st.session_state[f"{var_name}"] | |
for it_var_name in sessions_state_list: | |
delete_session_state_var(it_var_name) | |
#clear_inputs_garbages() | |
main_page() | |