malaknihed commited on
Commit
ca7b1df
·
verified ·
1 Parent(s): d1277d9
Files changed (1) hide show
  1. app.py +137 -2
app.py CHANGED
@@ -1,7 +1,142 @@
1
- from fastapi import FastAPI
 
2
  from fastapi.staticfiles import StaticFiles
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  app = FastAPI()
5
 
6
- # Servir les fichiers statiques (HTML, CSS, JS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  app.mount("/", StaticFiles(directory="static", html=True), name="static")
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile
2
+ from fastapi.responses import JSONResponse, RedirectResponse
3
  from fastapi.staticfiles import StaticFiles
4
+ from transformers import pipeline
5
+ import shutil
6
+ import os
7
+ import logging
8
+ from fastapi.middleware.cors import CORSMiddleware
9
+ from PyPDF2 import PdfReader
10
+ import docx
11
+ from PIL import Image # Pour ouvrir les images avant analyse
12
+ from pydantic import BaseModel
13
+
14
+ # Configuration du logging
15
+ logging.basicConfig(level=logging.INFO)
16
 
17
  app = FastAPI()
18
 
19
+ # Configuration CORS
20
+ app.add_middleware(
21
+ CORSMiddleware,
22
+ allow_origins=["*"],
23
+ allow_credentials=True,
24
+ allow_methods=["*"],
25
+ allow_headers=["*"],
26
+ )
27
+
28
+ UPLOAD_DIR = "uploads"
29
+ os.makedirs(UPLOAD_DIR, exist_ok=True)
30
+
31
+ # Charger les modèles avec gestion des erreurs
32
+ try:
33
+ summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
34
+ logging.info("✅ Modèle de résumé chargé avec succès !")
35
+ except Exception as e:
36
+ summarizer = None
37
+ logging.error(f"❌ Erreur chargement modèle résumé : {e}")
38
+
39
+ try:
40
+ image_captioning = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
41
+ logging.info("✅ Modèle d'image chargé avec succès !")
42
+ except Exception as e:
43
+ image_captioning = None
44
+ logging.error(f"❌ Erreur chargement modèle image : {e}")
45
+
46
+ try:
47
+ translator = pipeline("translation", model="facebook/m2m100_418M")
48
+ logging.info("✅ Modèle de traduction chargé avec succès !")
49
+ except Exception as e:
50
+ translator = None
51
+ logging.error(f"❌ Erreur chargement modèle traduction : {e}")
52
+
53
+
54
+ # ✅ Déclare les routes AVANT le montage des fichiers statiques
55
+ @app.post("/summarize/")
56
+ async def summarize_document(file: UploadFile = File(...)):
57
+ logging.info(f"📂 Requête reçue - Fichier : {file.filename}")
58
+
59
+ file_path = os.path.join(UPLOAD_DIR, file.filename)
60
+ with open(file_path, "wb") as buffer:
61
+ shutil.copyfileobj(file.file, buffer)
62
+
63
+ text = ""
64
+ if file.filename.endswith(".txt"):
65
+ with open(file_path, "r", encoding="utf-8") as f:
66
+ text = f.read()
67
+ elif file.filename.endswith(".pdf"):
68
+ try:
69
+ reader = PdfReader(file_path)
70
+ text = "\n".join([page.extract_text() or "" for page in reader.pages]).strip()
71
+ except Exception as e:
72
+ logging.error(f"❌ Erreur lecture PDF : {e}")
73
+ return JSONResponse(content={"error": "Impossible de lire le PDF"}, status_code=400)
74
+ elif file.filename.endswith(".docx"):
75
+ try:
76
+ doc = docx.Document(file_path)
77
+ text = "\n".join([para.text for para in doc.paragraphs]).strip()
78
+ except Exception as e:
79
+ logging.error(f"❌ Erreur lecture DOCX : {e}")
80
+ return JSONResponse(content={"error": "Impossible de lire le fichier DOCX"}, status_code=400)
81
+ else:
82
+ return JSONResponse(content={"error": "Format de fichier non supporté"}, status_code=400)
83
+
84
+ if not text:
85
+ logging.error("❌ Le fichier ne contient pas de texte lisible")
86
+ return JSONResponse(content={"error": "Le fichier est vide ou non lisible"}, status_code=400)
87
+
88
+ # Tronquer le texte pour éviter l'erreur "IndexError: index out of range"
89
+ max_input_length = 1024 # Limite du modèle
90
+ text = text[:max_input_length] # Tronquer le texte s'il est trop long
91
+
92
+ try:
93
+ summary = summarizer(text, max_length=150, min_length=50, do_sample=False)[0]["summary_text"]
94
+ return JSONResponse(content={"summary": summary})
95
+ except Exception as e:
96
+ logging.error(f"❌ Erreur lors du résumé : {e}")
97
+ return JSONResponse(content={"error": "Échec du résumé. Texte trop long ou format invalide."}, status_code=500)
98
+
99
+
100
+ @app.post("/interpret/")
101
+ async def interpret_image(file: UploadFile = File(...)):
102
+ logging.info(f"📂 Requête reçue - Image : {file.filename}")
103
+
104
+ file_path = os.path.join(UPLOAD_DIR, file.filename)
105
+ with open(file_path, "wb") as buffer:
106
+ shutil.copyfileobj(file.file, buffer)
107
+
108
+ try:
109
+ with Image.open(file_path) as img: # Charger l'image correctement
110
+ caption = image_captioning(img)[0]["generated_text"]
111
+ return JSONResponse(content={"caption": caption})
112
+ except Exception as e:
113
+ logging.error(f"❌ Erreur interprétation image : {e}")
114
+ return JSONResponse(content={"error": "Échec de l'analyse de l'image"}, status_code=400)
115
+
116
+ class TranslationRequest(BaseModel):
117
+ text: str
118
+ source_lang: str
119
+ target_lang: str
120
+
121
+ @app.post("/translate/")
122
+ async def translate_text(request: TranslationRequest):
123
+ if not request.text.strip():
124
+ return JSONResponse(content={"error": "Texte vide"}, status_code=400)
125
+
126
+ if translator is None:
127
+ return JSONResponse(content={"error": "Modèle de traduction non disponible"}, status_code=500)
128
+
129
+ try:
130
+ translated_text = translator(request.text, src_lang=request.source_lang, tgt_lang=request.target_lang)[0]["translation_text"]
131
+ return JSONResponse(content={"translated_text": translated_text})
132
+ except Exception as e:
133
+ logging.error(f"❌ Erreur de traduction : {e}")
134
+ return JSONResponse(content={"error": "Échec de la traduction"}, status_code=500)
135
+
136
+ # ✅ Déplace ici le montage des fichiers statiques
137
  app.mount("/", StaticFiles(directory="static", html=True), name="static")
138
+
139
+ # Redirection vers index.html
140
+ @app.get("/")
141
+ async def root():
142
+ return RedirectResponse(url="/index.html")