Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -250,6 +250,166 @@ plt.close()
|
|
| 250 |
|
| 251 |
except Exception as e:
|
| 252 |
return {"error": f"Erreur lors de la génération du graphique : {str(e)}"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
|
| 254 |
|
| 255 |
# Servir les fichiers statiques (HTML, CSS, JS)
|
|
|
|
| 250 |
|
| 251 |
except Exception as e:
|
| 252 |
return {"error": f"Erreur lors de la génération du graphique : {str(e)}"}
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
# Charger le modèle de résumé
|
| 260 |
+
summarizer = None
|
| 261 |
+
try:
|
| 262 |
+
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
|
| 263 |
+
logging.info("✅ Modèle de résumé chargé avec succès !")
|
| 264 |
+
except Exception as e:
|
| 265 |
+
logging.error(f"❌ Erreur chargement modèle résumé : {e}")
|
| 266 |
+
|
| 267 |
+
try:
|
| 268 |
+
image_captioning = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
|
| 269 |
+
logging.info("✅ Modèle d'image chargé avec succès !")
|
| 270 |
+
except Exception as e:
|
| 271 |
+
image_captioning = None
|
| 272 |
+
logging.error(f"❌ Erreur chargement modèle image : {e}")
|
| 273 |
+
|
| 274 |
+
# Fonction pour extraire le texte d'un fichier Word
|
| 275 |
+
def extract_text_from_docx(docx_file):
|
| 276 |
+
doc = Document(BytesIO(docx_file))
|
| 277 |
+
text = "\n".join([para.text for para in doc.paragraphs])
|
| 278 |
+
return text
|
| 279 |
+
|
| 280 |
+
# Fonction pour extraire le texte d'un fichier Excel
|
| 281 |
+
def extract_text_from_excel(xlsx_file):
|
| 282 |
+
# Utiliser pandas pour lire le fichier Excel
|
| 283 |
+
df = pd.read_excel(BytesIO(xlsx_file))
|
| 284 |
+
text = df.to_string(index=False)
|
| 285 |
+
return text
|
| 286 |
+
|
| 287 |
+
# Fonction pour extraire le texte d'un fichier PowerPoint
|
| 288 |
+
def extract_text_from_pptx(pptx_file):
|
| 289 |
+
presentation = Presentation(BytesIO(pptx_file))
|
| 290 |
+
text = ""
|
| 291 |
+
for slide in presentation.slides:
|
| 292 |
+
for shape in slide.shapes:
|
| 293 |
+
if hasattr(shape, "text"):
|
| 294 |
+
text += shape.text + "\n"
|
| 295 |
+
return text
|
| 296 |
+
|
| 297 |
+
# Endpoint pour la fonctionnalité de résumé
|
| 298 |
+
@app.post("/summarize/")
|
| 299 |
+
async def summarize(file: UploadFile = File(...)):
|
| 300 |
+
# Si le modèle n'est pas encore chargé, retourner un message indiquant que le modèle est en train de se charger
|
| 301 |
+
if summarizer is None:
|
| 302 |
+
return {"message": "Le modèle est en cours de chargement, veuillez patienter..."}
|
| 303 |
+
|
| 304 |
+
# Extraire le contenu du fichier téléchargé
|
| 305 |
+
contents = await file.read()
|
| 306 |
+
|
| 307 |
+
# Identifier le type de fichier et extraire le texte
|
| 308 |
+
if file.filename.endswith(".pdf"):
|
| 309 |
+
text = extract_text(BytesIO(contents))
|
| 310 |
+
elif file.filename.endswith(".docx"):
|
| 311 |
+
text = extract_text_from_docx(contents)
|
| 312 |
+
elif file.filename.endswith(".xls") or file.filename.endswith(".xlsx"):
|
| 313 |
+
text = extract_text_from_excel(contents)
|
| 314 |
+
elif file.filename.endswith(".pptx") or file.filename.endswith(".ppt"):
|
| 315 |
+
text = extract_text_from_pptx(contents)
|
| 316 |
+
else:
|
| 317 |
+
return {"summary": "Résumé non disponible pour ce format de fichier."}
|
| 318 |
+
|
| 319 |
+
# Si un modèle de résumé est chargé, effectuer le résumé
|
| 320 |
+
try:
|
| 321 |
+
if summarizer:
|
| 322 |
+
summary = summarizer(text[:1024]) # Limiter la taille d'entrée pour le modèle
|
| 323 |
+
summary_text = summary[0]['summary_text']
|
| 324 |
+
else:
|
| 325 |
+
summary_text = "❌ Modèle de résumé non disponible."
|
| 326 |
+
except Exception as e:
|
| 327 |
+
summary_text = f"❌ Erreur lors de la génération du résumé : {e}"
|
| 328 |
+
|
| 329 |
+
# Retourner le résumé généré
|
| 330 |
+
return {"summary": summary_text}
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
@app.post("/image-caption/")
|
| 334 |
+
async def caption_image(file: UploadFile = File(...)):
|
| 335 |
+
if image_captioning is None:
|
| 336 |
+
return JSONResponse(content={"error": "Le modèle de captioning n'est pas disponible."}, status_code=500)
|
| 337 |
+
|
| 338 |
+
try:
|
| 339 |
+
contents = await file.read()
|
| 340 |
+
image = Image.open(io.BytesIO(contents)).convert("RGB")
|
| 341 |
+
result = image_captioning(image)
|
| 342 |
+
caption = result[0]['generated_text']
|
| 343 |
+
return {"caption": caption}
|
| 344 |
+
except Exception as e:
|
| 345 |
+
return JSONResponse(content={"error": str(e)}, status_code=500)
|
| 346 |
+
|
| 347 |
+
try:
|
| 348 |
+
qa_pipeline = pipeline("question-answering", model="deepset/roberta-base-squad2")
|
| 349 |
+
logging.info("✅ Modèle QA Texte chargé avec succès !")
|
| 350 |
+
except Exception as e:
|
| 351 |
+
qa_pipeline = None
|
| 352 |
+
logging.error(f"❌ Erreur chargement modèle QA Texte : {e}")
|
| 353 |
+
try:
|
| 354 |
+
image_qa_pipeline = pipeline("visual-question-answering", model="Salesforce/blip-vqa-base")
|
| 355 |
+
logging.info("✅ Modèle QA Image chargé avec succès !")
|
| 356 |
+
except Exception as e:
|
| 357 |
+
image_qa_pipeline = None
|
| 358 |
+
logging.error(f"❌ Erreur chargement modèle QA Image : {e}")
|
| 359 |
+
|
| 360 |
+
@app.post("/doc-qa/")
|
| 361 |
+
async def doc_question_answer(file: UploadFile = File(...), question: str = Form(...)):
|
| 362 |
+
if qa_pipeline is None:
|
| 363 |
+
return JSONResponse(content={"error": "Modèle indisponible."}, status_code=500)
|
| 364 |
+
|
| 365 |
+
try:
|
| 366 |
+
contents = await file.read()
|
| 367 |
+
filename = file.filename.lower()
|
| 368 |
+
|
| 369 |
+
if filename.endswith(".docx"):
|
| 370 |
+
with open("temp.docx", "wb") as f:
|
| 371 |
+
f.write(contents)
|
| 372 |
+
context = docx2txt.process("temp.docx")
|
| 373 |
+
|
| 374 |
+
elif filename.endswith((".xlsx", ".xls")):
|
| 375 |
+
df = pd.read_excel(BytesIO(contents))
|
| 376 |
+
context = df.to_string(index=False)
|
| 377 |
+
|
| 378 |
+
elif filename.endswith(".pptx"):
|
| 379 |
+
presentation = Presentation(BytesIO(contents))
|
| 380 |
+
context = ""
|
| 381 |
+
for slide in presentation.slides:
|
| 382 |
+
for shape in slide.shapes:
|
| 383 |
+
if hasattr(shape, "text"):
|
| 384 |
+
context += shape.text + "\n"
|
| 385 |
+
|
| 386 |
+
elif filename.endswith(".pdf"):
|
| 387 |
+
context = extract_text(BytesIO(contents))
|
| 388 |
+
|
| 389 |
+
else:
|
| 390 |
+
return JSONResponse(content={"error": "Format non supporté."}, status_code=400)
|
| 391 |
+
|
| 392 |
+
result = qa_pipeline(question=question, context=context)
|
| 393 |
+
return {"answer": result["answer"]}
|
| 394 |
+
|
| 395 |
+
except Exception as e:
|
| 396 |
+
return JSONResponse(content={"error": str(e)}, status_code=500)
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
@app.post("/image-qa/")
|
| 400 |
+
async def image_qa(file: UploadFile = File(...), question: str = Form(...)):
|
| 401 |
+
if image_qa_pipeline is None:
|
| 402 |
+
return JSONResponse(content={"error": "Le modèle n'est pas disponible."}, status_code=500)
|
| 403 |
+
|
| 404 |
+
try:
|
| 405 |
+
contents = await file.read()
|
| 406 |
+
image = Image.open(io.BytesIO(contents)).convert("RGB")
|
| 407 |
+
result = image_qa_pipeline(image=image, question=question)
|
| 408 |
+
answer = result[0]['answer']
|
| 409 |
+
return {"answer": answer}
|
| 410 |
+
except Exception as e:
|
| 411 |
+
return JSONResponse(content={"error": str(e)}, status_code=500)
|
| 412 |
+
|
| 413 |
|
| 414 |
|
| 415 |
# Servir les fichiers statiques (HTML, CSS, JS)
|