LewisBabong commited on
Commit
1e35d8d
·
verified ·
1 Parent(s): da0be3a

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +327 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import tempfile
4
+ import uuid
5
+ import os
6
+ from dotenv import load_dotenv
7
+
8
+ load_dotenv() # charge les variables depuis le fichier .env
9
+ # === Nouvelle clé API et modèles plus performants ===
10
+ HF_TOKEN_SECRET = os.getenv("HF_TOKEN_SECRET")
11
+ HF_TOKEN = f"Bearer {HF_TOKEN_SECRET}"
12
+
13
+
14
+ # === Configuration de la page ===
15
+ st.set_page_config(
16
+ page_title="🧠 NLP Magique avec Hugging Face",
17
+ page_icon="✨",
18
+ layout="wide"
19
+ )
20
+
21
+ # === CSS personnalisé haut de gamme ===
22
+ st.markdown("""
23
+ <style>
24
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
25
+ .stApp {
26
+ background: linear-gradient(135deg, #e0e7ff, #c4b5fd);
27
+ font-family: 'Poppins', sans-serif;
28
+ padding: 1.5rem;
29
+ min-height: 100vh;
30
+ }
31
+ .title {
32
+ text-align: center;
33
+ font-size: 4em;
34
+ font-weight: 700;
35
+ color: #5B21B6;
36
+ margin-bottom: 1.5rem;
37
+ animation: fadeIn 1.5s ease-in-out;
38
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
39
+ }
40
+ .subheader {
41
+ color: #4C1D95;
42
+ font-size: 2em;
43
+ margin: 2rem 0 1rem;
44
+ font-weight: 600;
45
+ text-shadow: 1px 1px 3px rgba(0,0,0,0.1);
46
+ }
47
+ .card {
48
+ background: rgba(255,255,255,0.9);
49
+ border-radius: 15px;
50
+ padding: 2rem;
51
+ margin: 1rem 0;
52
+ box-shadow: 0 8px 20px rgba(0,0,0,0.1);
53
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
54
+ }
55
+ .card:hover {
56
+ transform: translateY(-5px);
57
+ box-shadow: 0 12px 25px rgba(0,0,0,0.15);
58
+ }
59
+ .stButton>button {
60
+ background: linear-gradient(45deg, #7C3AED, #A78BFA);
61
+ color: white;
62
+ font-weight: 600;
63
+ border-radius: 12px;
64
+ padding: 15px 35px;
65
+ border: none;
66
+ box-shadow: 0 6px 15px rgba(0,0,0,0.2);
67
+ transition: all 0.3s ease;
68
+ }
69
+ .stButton>button:hover {
70
+ background: linear-gradient(45deg, #5B21B6, #7C3AED);
71
+ transform: translateY(-3px);
72
+ box-shadow: 0 10px 20px rgba(0,0,0,0.25);
73
+ }
74
+ .stTextArea textarea, .stSlider>div {
75
+ background: #f8fafc;
76
+ border-radius: 12px;
77
+ padding: 15px;
78
+ font-size: 1.1em;
79
+ border: 1px solid #d1d5db;
80
+ box-shadow: inset 0 2px 5px rgba(0,0,0,0.05);
81
+ transition: all 0.3s ease;
82
+ }
83
+ .stTextArea textarea:focus, .stSlider>div:focus {
84
+ border-color: #7C3AED;
85
+ box-shadow: 0 0 8px rgba(124,58,237,0.3);
86
+ outline: none;
87
+ }
88
+ .stTabs [data-baseweb="tab-list"] {
89
+ background: rgba(255,255,255,0.1);
90
+ backdrop-filter: blur(10px);
91
+ padding: 12px 20px;
92
+ border-radius: 15px;
93
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
94
+ position: sticky;
95
+ top: 0;
96
+ z-index: 100;
97
+ display: flex;
98
+ align-items: center;
99
+ gap: 10px;
100
+ }
101
+ .stTabs [data-baseweb="tab"] {
102
+ color: #000;
103
+ font-weight: 600;
104
+ font-size: 1.2em;
105
+ padding: 12px 25px;
106
+ border-radius: 10px;
107
+ transition: all 0.3s ease;
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 8px;
111
+ }
112
+ .stTabs [data-baseweb="tab"]:hover {
113
+ background: rgba(124,58,237,0.3);
114
+ color: white;
115
+ }
116
+ .stTabs [aria-selected="true"] {
117
+ background: #7C3AED;
118
+ color: white;
119
+ box-shadow: 0 3px 8px rgba(0,0,0,0.2);
120
+ }
121
+ .stFileUploader {
122
+ background: #f8fafc;
123
+ border-radius: 12px;
124
+ padding: 15px;
125
+ border: 1px solid #d1d5db;
126
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
127
+ }
128
+ .stFileUploader:hover {
129
+ border-color: #7C3AED;
130
+ }
131
+ .stSpinner .spinner {
132
+ border-top-color: #7C3AED;
133
+ }
134
+ .output-card {
135
+ background: #f8fafc;
136
+ border-radius: 12px;
137
+ padding: 1.5rem;
138
+ margin-top: 1rem;
139
+ border: 1px solid #e5e7eb;
140
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
141
+ position: relative;
142
+ }
143
+ .copy-button {
144
+ position: absolute;
145
+ top: 10px;
146
+ right: 10px;
147
+ background: #7C3AED;
148
+ color: white;
149
+ border: none;
150
+ border-radius: 8px;
151
+ padding: 8px 12px;
152
+ cursor: pointer;
153
+ transition: background 0.3s ease;
154
+ }
155
+ .copy-button:hover {
156
+ background: #5B21B6;
157
+ }
158
+ @keyframes fadeIn {
159
+ from { opacity: 0; transform: translateY(-20px); }
160
+ to { opacity: 1; transform: translateY(0); }
161
+ }
162
+ .footer {
163
+ text-align: center;
164
+ font-size: 1.2em;
165
+ color: #4C1D95;
166
+ margin-top: 3rem;
167
+ padding: 1.5rem;
168
+ background: rgba(255,255,255,0.9);
169
+ border-radius: 15px;
170
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
171
+ animation: glow 3s ease-in-out infinite;
172
+ }
173
+ .footer a {
174
+ color: #7C3AED;
175
+ text-decoration: none;
176
+ font-weight: 600;
177
+ transition: color 0.3s ease;
178
+ }
179
+ .footer a:hover {
180
+ color: #5B21B6;
181
+ text-decoration: underline;
182
+ }
183
+ .social-icons img {
184
+ width: 30px;
185
+ margin: 0 10px;
186
+ transition: transform 0.3s ease;
187
+ }
188
+ .social-icons img:hover {
189
+ transform: scale(1.2);
190
+ }
191
+ @keyframes glow {
192
+ 0% { box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
193
+ 50% { box-shadow: 0 4px 20px rgba(124,58,237,0.3); }
194
+ 100% { box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
195
+ }
196
+ @media (max-width: 768px) {
197
+ .title { font-size: 2.5em; }
198
+ .subheader { font-size: 1.5em; }
199
+ .stTabs [data-baseweb="tab"] { font-size: 1em; padding: 10px 15px; }
200
+ .card { padding: 1.5rem; }
201
+ }
202
+ </style>
203
+ """, unsafe_allow_html=True)
204
+
205
+ # === JavaScript pour la fonctionnalité de copie ===
206
+ st.markdown("""
207
+ <script>
208
+ function copyToClipboard(text) {
209
+ navigator.clipboard.writeText(text).then(() => {
210
+ alert('Texte copié dans le presse-papiers !');
211
+ });
212
+ }
213
+ </script>
214
+ """, unsafe_allow_html=True)
215
+
216
+
217
+ # === Fonctions API ===
218
+
219
+ def generate_text(prompt):
220
+ url = "https://api-inference.huggingface.co/models/gpt2"
221
+ headers = {"Authorization": HF_TOKEN}
222
+ payload = {"inputs": f"{prompt}"}
223
+ response = requests.post(url, headers=headers, json=payload)
224
+ if response.ok:
225
+ return response.json()[0]["generated_text"]
226
+ else:
227
+ st.error(f"Erreur FLAN-T5: {response.status_code} - {response.text}")
228
+ return "Erreur lors de la génération."
229
+
230
+
231
+ def summarize_text(text):
232
+ url = "https://api-inference.huggingface.co/models/facebook/bart-large-cnn"
233
+ headers = {"Authorization": HF_TOKEN}
234
+ payload = {"inputs": text}
235
+ response = requests.post(url, headers=headers, json=payload)
236
+ if response.ok:
237
+ return response.json()[0]["summary_text"]
238
+ else:
239
+ st.error(f"Erreur BART: {response.status_code} - {response.text}")
240
+ return "Erreur lors du résumé."
241
+
242
+
243
+ def transcribe_audio(path):
244
+ url = "https://api-inference.huggingface.co/models/openai/whisper-large"
245
+ headers = {
246
+ "Authorization": HF_TOKEN,
247
+ "Content-Type": "application/octet-stream"
248
+ }
249
+ with open(path, "rb") as f:
250
+ response = requests.post(url, headers=headers, data=f)
251
+ if response.ok:
252
+ return response.json()["text"]
253
+ else:
254
+ st.error(f"Erreur Whisper Large: {response.status_code} - {response.text}")
255
+ return "Erreur lors de la transcription."
256
+
257
+
258
+ # === Titre principal ===
259
+ st.markdown('<div class="title">✨ NLP Magique avec Hugging Face ✨</div>', unsafe_allow_html=True)
260
+ st.markdown("---")
261
+
262
+ # === AppBar avec onglets ===
263
+ tabs = st.tabs([ f"📄 Résumeur", f"📝 Générateur", f"🎧 Transcripteur"])
264
+
265
+ # === Générateur de texte ===
266
+ with tabs[1]:
267
+ st.markdown('<div class="subheader">📝 Génération de contenu créatif</div>', unsafe_allow_html=True)
268
+ with st.container():
269
+ st.markdown('<div class="card">', unsafe_allow_html=True)
270
+ prompt = st.text_area("💡 Saisissez une idée ou une phrase :", "La médecine moderne", height=150,
271
+ placeholder="Entrez votre texte ici...")
272
+ temp = st.slider("🎯 Niveau de créativité", 0.1, 1.0, 0.7, step=0.1)
273
+ if st.button("🚀 Générer"):
274
+ with st.spinner("Génération en cours..."):
275
+ output = generate_text(prompt)
276
+ st.markdown(
277
+ f'<div class="output-card">{output}<button class="copy-button" onclick="copyToClipboard(\'{output}\')">Copier</button></div>',
278
+ unsafe_allow_html=True)
279
+ st.markdown('</div>', unsafe_allow_html=True)
280
+
281
+ # === Résumeur de texte ===
282
+ with tabs[0]:
283
+ st.markdown('<div class="subheader">📄 Synthèse intelligente de textes</div>', unsafe_allow_html=True)
284
+ with st.container():
285
+ st.markdown('<div class="card">', unsafe_allow_html=True)
286
+ texte = st.text_area("✍️ Collez votre texte à résumer :", height=200, placeholder="Collez un long texte ici...")
287
+ if st.button("🧠 Résumer"):
288
+ with st.spinner("Analyse et synthèse en cours..."):
289
+ summary = summarize_text(texte)
290
+ st.markdown(
291
+ f'<div class="output-card">{summary}<button class="copy-button" onclick="copyToClipboard(\'{summary}\')">Copier</button></div>',
292
+ unsafe_allow_html=True)
293
+ st.markdown('</div>', unsafe_allow_html=True)
294
+
295
+ # === Transcription audio ===
296
+ with tabs[2]:
297
+ st.markdown('<div class="subheader">🎧 Transcription automatisée d’audio</div>', unsafe_allow_html=True)
298
+ with st.container():
299
+ st.markdown('<div class="card">', unsafe_allow_html=True)
300
+ audio_file = st.file_uploader("🎵 Chargez un fichier audio (max 30s)", type=["wav", "mp3", "m4a"],
301
+ help="Formats supportés : WAV, MP3, M4A")
302
+ if audio_file is not None:
303
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
304
+ tmp_file.write(audio_file.read())
305
+ audio_path = tmp_file.name
306
+ st.audio(audio_path)
307
+ if st.button("✍️ Transcrire"):
308
+ with st.spinner("Transcription en cours..."):
309
+ transcript = transcribe_audio(audio_path)
310
+ st.markdown(
311
+ f'<div class="output-card">{transcript}<button class="copy-button" onclick="copyToClipboard(\'{transcript}\')">Copier</button></div>',
312
+ unsafe_allow_html=True)
313
+ st.markdown('</div>', unsafe_allow_html=True)
314
+
315
+ # === Pied de page amélioré ===
316
+ st.markdown("---")
317
+ st.markdown("""
318
+ <div class="footer">
319
+ <p>✨ Propriété intellectuelle de NTONGA BABONG Entrepreneur<br>
320
+ Créé avec ❤️ grâce à <a href='https://huggingface.co/' target='_blank'>Hugging Face</a> et <a href='https://streamlit.io' target='_blank'>Streamlit</a></p>
321
+ <div class="social-icons">
322
+ <a href="https://twitter.com" target="_blank"><img src="https://img.icons8.com/color/48/000000/twitter--v1.png"/></a>
323
+ <a href="https://linkedin.com" target="_blank"><img src="https://img.icons8.com/color/48/000000/linkedin.png"/></a>
324
+ <a href="https://github.com" target="_blank"><img src="https://img.icons8.com/color/48/000000/github--v1.png"/></a>
325
+ </div>
326
+ </div>
327
+ """, unsafe_allow_html=True)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit
2
+ requests
3
+
4
+ python-dotenv