Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| import re | |
| import tempfile | |
| import os | |
| from dotenv import load_dotenv | |
| # Nouveaux imports pour Groq et LangSmith | |
| from groq import Groq | |
| from langsmith import traceable | |
| # Charger les variables d'environnement | |
| load_dotenv() | |
| # --- INTERFACE STREAMLIT --- | |
| st.set_page_config(page_title="nlp", layout="wide") | |
| st.title("SN NATURAL LANGUAGE PROCESSING") | |
| st.subheader('Étudiant MASTER II: TATSA TCHINDA Colince') | |
| # Sidebar logo | |
| try: | |
| image_path = 'src/Keyce.jpg' | |
| st.sidebar.image(image_path, caption="Keyce informatique et intelligence artificielle", use_container_width=True) | |
| except FileNotFoundError: | |
| st.sidebar.warning("Image 'keyce.jpg' non trouvée. Assurez-vous qu'elle est dans le même répertoire que le script.") | |
| # --- GESTION DES CLÉS API (depuis .env) --- | |
| st.session_state["API_TOKEN_HF"] = os.getenv("HUGGINGFACE_API_KEY") | |
| st.session_state["API_TOKEN_GROQ"] = os.getenv("GROQ_API_KEY") | |
| api_token_langsmith = os.getenv("LANGCHAIN_API_KEY") | |
| # Configuration de LangSmith si la clé est fournie | |
| if api_token_langsmith: | |
| st.session_state["LANGSMITH_CONFIGURED"] = True | |
| os.environ["LANGCHAIN_TRACING_V2"] = "true" | |
| os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com" | |
| os.environ["LANGCHAIN_API_KEY"] = api_token_langsmith | |
| os.environ["LANGCHAIN_PROJECT"] = "Mon App Streamlit NLP" # Nom du projet dans LangSmith | |
| st.sidebar.info("Tracing LangSmith activé.") | |
| else: | |
| st.session_state["LANGSMITH_CONFIGURED"] = False | |
| # Désactiver le tracing si aucune clé n'est fournie | |
| if "LANGCHAIN_TRACING_V2" in os.environ: | |
| del os.environ["LANGCHAIN_TRACING_V2"] | |
| # --- INITIALISATION DES CLIENTS --- | |
| headers = {} | |
| if st.session_state.get("API_TOKEN_HF"): | |
| headers = {"Authorization": f"Bearer {st.session_state['API_TOKEN_HF']}"} | |
| # --- FONCTIONS UTILES --- | |
| def nettoyer_reponse(text): | |
| # La fonction de nettoyage n'est plus nécessaire pour Groq, mais on la garde au cas où. | |
| cleaned = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL) | |
| return cleaned.strip() | |
| # Le décorateur @traceable active le suivi LangSmith | |
| def generate_with_groq_llama(prompt, api_key): | |
| """ | |
| Génère du texte en utilisant l'API Groq avec un modèle Llama3 et trace l'appel avec LangSmith. | |
| """ | |
| try: | |
| client_groq = Groq(api_key=api_key) | |
| chat_completion = client_groq.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": prompt, | |
| } | |
| ], | |
| model="llama3-8b-8192", | |
| temperature=0.7, | |
| max_tokens=1024, | |
| ) | |
| return chat_completion.choices[0].message.content | |
| except Groq.APIConnectionError as e: | |
| st.error(f"Erreur de connexion avec Groq: {e.__cause__}") | |
| return "Impossible de se connecter à l'API Groq. Veuillez vérifier votre connexion réseau." | |
| except Exception as e: | |
| st.error(f"Une erreur inattendue est survenue avec Groq: {e}") | |
| return "Une erreur est survenue lors de la génération de texte." | |
| def transcribe_audio(path, content_type): | |
| request_headers = headers.copy() | |
| if not request_headers.get("Authorization"): | |
| st.error("Veuillez entrer une clé API Hugging Face pour utiliser cette fonctionnalité.") | |
| return "Erreur : clé API Hugging Face manquante." | |
| request_headers["Content-Type"] = content_type | |
| API_URL = "https://api-inference.huggingface.co/models/openai/whisper-large-v2" | |
| # Débogage | |
| st.info(f"Tentative de transcription audio...") | |
| st.info(f"Chemin du fichier audio : {path}") | |
| st.info(f"Type de contenu (Content-Type) : {content_type}") | |
| st.info(f"En-têtes de la requête (partie Authorization masquée) : {{'Authorization': 'Bearer [MASQUÉE]', 'Content-Type': '{content_type}'}}") | |
| if not st.session_state.get("API_TOKEN_HF"): | |
| st.error("DEBUG: La clé API Hugging Face n'est PAS présente dans st.session_state.") | |
| else: | |
| st.success("DEBUG: La clé API Hugging Face est présente dans st.session_state.") | |
| try: | |
| with open(path, "rb") as f: | |
| response = requests.post(API_URL, headers=request_headers, data=f) | |
| response.raise_for_status() # Lève une exception pour les codes d'erreur HTTP | |
| return response.json().get("text", "Erreur: 'text' non trouvé dans la réponse.") | |
| except requests.exceptions.HTTPError as err: | |
| st.error(f"Erreur Whisper Large: {err.response.status_code} - {err.response.text}") | |
| return f"Erreur lors de la transcription (Code: {err.response.status_code}). Vérifiez votre clé API HF et les limites d'utilisation." | |
| except Exception as e: | |
| st.error(f"Une erreur inattendue est survenue lors de la transcription : {str(e)}") | |
| return "Erreur lors de la transcription." | |
| def summarize_text(text): | |
| """ | |
| Génère un résumé de texte en utilisant le modèle Groq Llama3. | |
| """ | |
| if not st.session_state.get("API_TOKEN_GROQ"): | |
| st.error("Veuillez configurer votre clé API Groq dans le fichier .env pour le résumé.") | |
| return "Erreur : clé API Groq manquante." | |
| prompt = f"Résume le texte suivant de manière concise en français :\n\nTexte : '''{text}'''\n\nRésumé :" | |
| summary = generate_with_groq_llama(prompt, st.session_state["API_TOKEN_GROQ"]) | |
| return summary | |
| # --- MENU --- | |
| option = st.sidebar.radio( | |
| "Choisissez une fonctionnalité :", | |
| ["📝 Générateur de texte", "🎙 Audio vers texte", "🧠 Résumeur de texte"] | |
| ) | |
| # --- GÉNÉRATEUR DE TEXTE --- | |
| if option == "📝 Générateur de texte": | |
| st.subheader("📝 Génération de texte (Groq Llama3)") | |
| st.markdown("Utilise le modèle `llama3-8b-8192` via l'API ultra-rapide de Groq.") | |
| if st.session_state.get("LANGSMITH_CONFIGURED"): | |
| st.info("Le suivi avec LangSmith est activé. [Voir le projet](https://smith.langchain.com/)", icon="🔗") | |
| if not st.session_state.get("API_TOKEN_GROQ"): | |
| st.warning("Veuillez entrer une clé API Groq dans votre fichier `.env` pour utiliser le générateur de texte.") | |
| else: | |
| prompt = st.text_area("Entrez votre prompt :", key="prompt", height=150) | |
| if st.button("Générer", key="gen"): | |
| if prompt.strip(): | |
| with st.spinner("Génération en cours avec Groq..."): | |
| try: | |
| output = generate_with_groq_llama(prompt, st.session_state["API_TOKEN_GROQ"]) | |
| st.success("Texte généré :") | |
| st.write(output) | |
| except Exception as e: | |
| st.error(f"Erreur lors de la génération avec Groq : {e}") | |
| else: | |
| st.warning("Veuillez entrer un prompt.") | |
| # --- AUDIO VERS TEXTE --- | |
| elif option == "🎙 Audio vers texte": | |
| st.subheader("🎧 Transcription automatisée d’un fichier audio (30 sec max)") | |
| if not st.session_state.get("API_TOKEN_HF"): | |
| st.warning("Veuillez entrer une clé API Hugging Face dans votre fichier `.env` pour utiliser cette fonctionnalité.") | |
| else: | |
| audio_file = st.file_uploader("🎵 Chargez un fichier audio", type=["wav", "mp3", "m4a"]) | |
| if audio_file is not None: | |
| # Créer un fichier temporaire pour sauvegarder l'audio | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=f'.{audio_file.name.split(".")[-1]}') as tmp_file: | |
| tmp_file.write(audio_file.getvalue()) | |
| audio_path = tmp_file.name | |
| st.audio(audio_path) | |
| if st.button("✍️ Transcrire"): | |
| with st.spinner("Transcription en cours..."): | |
| # On passe le type MIME du fichier original à la fonction | |
| transcript = transcribe_audio(audio_path, audio_file.type) | |
| if "Erreur" not in transcript: # Vérifiez si la transcription n'est pas une erreur | |
| st.markdown(f"**Transcription :**") | |
| st.text_area("Résultat", transcript, height=150) | |
| # Nettoyer le fichier temporaire | |
| os.unlink(audio_path) | |
| # --- RÉSUMEUR DE TEXTE --- | |
| elif option == "🧠 Résumeur de texte": | |
| st.subheader("🧠 Résumé de texte (Groq Llama3)") | |
| st.markdown("Utilise le modèle `llama3-8b-8192` pour générer un résumé.") | |
| if not st.session_state.get("API_TOKEN_GROQ"): | |
| st.warning("Veuillez vous assurer qu'une clé API Groq est configurée dans votre fichier .env pour utiliser cette fonctionnalité.") | |
| else: | |
| input_text = st.text_area("Texte à résumer :", height=300) | |
| if st.button("Résumer"): | |
| if input_text.strip(): | |
| with st.spinner("Résumé en cours avec Groq..."): | |
| summary = summarize_text(input_text) | |
| st.success("Résumé généré :") | |
| st.write(summary) | |
| else: | |
| st.warning("Veuillez entrer un texte à résumer.") |