Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| import re | |
| from huggingface_hub import InferenceClient | |
| import tempfile | |
| # ========= INTERFACE STREAMLIT ========= | |
| st.set_page_config(page_title="nlp", layout="wide") | |
| st.title("CC NATURAL LANGUAGE PROCESSING") | |
| st.subheader('Etudiant MASTER II: TATSA TCHINDA Colince') | |
| # Sidebar logo | |
| image_path = 'keyce.jpg' | |
| st.sidebar.image(image_path, caption="Keyce informatique et intelligence artificielle", use_container_width=True) | |
| # ========= ACCÈS PAR API TOKEN ========= | |
| st.sidebar.markdown("### 🔐 Clé API Hugging Face requise") | |
| api_token = st.sidebar.text_input("Clé Hugging Face", type="password") | |
| if api_token: | |
| st.session_state["API_TOKEN"] = api_token | |
| else: | |
| st.warning("Veuillez entrer une clé API Hugging Face dans le sidebar, pour accéder à l’application.") | |
| st.stop() | |
| headers = {"Authorization": f"Bearer {api_token}"} | |
| # ========= INITIALISATION CLIENT HF ========= | |
| client = InferenceClient(api_key=api_token) | |
| # ========= FONCTIONS UTILES ========= | |
| def nettoyer_reponse(text): | |
| cleaned = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL) | |
| return cleaned.strip() | |
| def generate_with_deepseek(prompt, token): | |
| deepseek_client = InferenceClient(provider="fireworks-ai", api_key=token) | |
| completion = deepseek_client.chat.completions.create( | |
| model="deepseek-ai/DeepSeek-R1", | |
| messages=[{"role": "user", "content": prompt}], | |
| max_tokens=512, | |
| ) | |
| return nettoyer_reponse(completion.choices[0].message.content) | |
| def transcribe_audio(path): | |
| try: | |
| with open(path, "rb") as f: | |
| audio_bytes = f.read() | |
| output = client.automatic_speech_recognition( | |
| audio=audio_bytes, | |
| model="openai/whisper-small" # ou "jonatasgrosman/whisper-small-fr" | |
| ) | |
| return output["text"] | |
| except Exception as e: | |
| st.error(f"Erreur lors de la transcription : {str(e)}") | |
| return "Erreur lors de la transcription." | |
| def summarize_text(text): | |
| payload = {"inputs": text} | |
| response = requests.post( | |
| "https://api-inference.huggingface.co/models/facebook/bart-large-cnn", | |
| headers=headers, | |
| json=payload, | |
| ) | |
| return response.json()[0]["summary_text"] | |
| # ========= 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 (DeepSeek-R1)") | |
| prompt = st.text_area("Entrez votre prompt :", key="prompt") | |
| if st.button("Générer", key="gen"): | |
| if prompt.strip(): | |
| with st.spinner("Génération..."): | |
| try: | |
| output = generate_with_deepseek(prompt, api_token) | |
| st.success("Texte généré :") | |
| st.write(output) | |
| except Exception as e: | |
| st.error(f"Erreur : {e}") | |
| else: | |
| st.warning("Veuillez entrer un prompt.") | |
| # ========= AUDIO VERS TEXTE ========= | |
| elif option == "🎙 Audio vers texte": | |
| st.markdown('<div class="subheader">🎧 Transcription automatisée d’un fichier audio (30 sec max)</div>', unsafe_allow_html=True) | |
| with st.container(): | |
| st.markdown('<div class="card">', unsafe_allow_html=True) | |
| audio_file = st.file_uploader("🎵 Chargez un fichier audio (30 secondes max)", type=["wav", "mp3", "m4a"], | |
| help="Formats supportés : WAV, MP3, M4A") | |
| if audio_file is not None: | |
| with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file: | |
| tmp_file.write(audio_file.read()) | |
| audio_path = tmp_file.name | |
| st.audio(audio_path) | |
| if st.button("✍️ Transcrire"): | |
| with st.spinner("Transcription en cours..."): | |
| transcript = transcribe_audio(audio_path) | |
| st.markdown( | |
| f'<div class="output-card">{transcript}<button class="copy-button" onclick="copyToClipboard(\'{transcript}\')">Copier</button></div>', | |
| unsafe_allow_html=True) | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| # ========= RÉSUMEUR DE TEXTE ========= | |
| elif option == "🧠 Résumeur de texte": | |
| st.subheader("🧠 Résumé de texte") | |
| 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..."): | |
| try: | |
| summary = summarize_text(input_text) | |
| st.success("Résumé généré :") | |
| st.write(summary) | |
| except Exception as e: | |
| st.error(f"Erreur : {e}") | |
| else: | |
| st.warning("Veuillez entrer un texte à résumer.") | |