malaknihed commited on
Commit
d5f775d
·
verified ·
1 Parent(s): 88cde13
Files changed (1) hide show
  1. app.py +33 -141
app.py CHANGED
@@ -1,158 +1,50 @@
1
- from fastapi import FastAPI, File, UploadFile # type: ignore
2
- from transformers import pipeline, AutoTokenizer
3
- import pdfplumber # type: ignore
4
- import docx # type: ignore
5
- import pptx # type: ignore
6
- import pandas as pd # type: ignore
7
- from PIL import Image
8
- import io
9
- from fastapi.middleware.cors import CORSMiddleware # type: ignore
10
- import uvicorn
11
 
12
  app = FastAPI()
13
 
14
- # Activer CORS pour autoriser les requêtes depuis le navigateur
15
- app.add_middleware(
16
- CORSMiddleware,
17
- allow_origins=["*"], # Autoriser toutes les origines (mettre ["http://127.0.0.1:5500"] si nécessaire)
18
- allow_credentials=True,
19
- allow_methods=["*"], # Autoriser toutes les méthodes (GET, POST, etc.)
20
- allow_headers=["*"], # Autoriser tous les headers
21
- )
22
 
 
 
23
 
24
- # 🔹 TEST : Vérifier si FastAPI démarre bien
25
- @app.get("/")
26
- def home():
27
- return {"message": "Serveur FastAPI en ligne 🚀"}
28
 
29
- # Charger les modèles Hugging Face avec debug
30
- print("⏳ Chargement du modèle de résumé...")
31
- try:
32
- summarizer = pipeline("summarization", model="google/flan-t5-large")
33
- print("✅ Modèle de résumé chargé.")
34
- except Exception as e:
35
- print(f"❌ Erreur lors du chargement du modèle de résumé : {e}")
36
 
37
- print("⏳ Chargement du modèle d'interprétation d'image...")
38
- try:
39
- image_captioner = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
40
- print("✅ Modèle d'interprétation d'image chargé.")
41
- except Exception as e:
42
- print(f"❌ Erreur lors du chargement du modèle d'interprétation d'image : {e}")
43
-
44
- # Charger le tokenizer pour limiter la taille du texte
45
- tokenizer = AutoTokenizer.from_pretrained("google/flan-t5-large")
46
-
47
- # Fonction pour extraire le texte d'un fichier
48
- def extract_text_from_file(file: UploadFile):
49
- print(f"🔹 Extraction du texte depuis : {file.filename}")
50
-
51
- try:
52
- if file.filename.endswith(".pdf"):
53
- with pdfplumber.open(file.file) as pdf:
54
- text = " ".join([page.extract_text() for page in pdf.pages if page.extract_text()])
55
- print("✅ Texte extrait depuis PDF :", text[:500]) # Afficher les 500 premiers caractères
56
- return text
57
- elif file.filename.endswith(".docx"):
58
- doc = docx.Document(file.file)
59
- text = " ".join([para.text for para in doc.paragraphs])
60
- print("✅ Texte extrait depuis DOCX :", text[:500])
61
- return text
62
- elif file.filename.endswith(".pptx"):
63
- ppt = pptx.Presentation(file.file)
64
- text = " ".join([shape.text for slide in ppt.slides for shape in slide.shapes if hasattr(shape, "text")])
65
- print("✅ Texte extrait depuis PPTX :", text[:500])
66
- return text
67
- elif file.filename.endswith(".xlsx"):
68
- df = pd.read_excel(file.file)
69
- text = " ".join(df.astype(str).values.flatten())
70
- print("✅ Texte extrait depuis XLSX :", text[:500])
71
- return text
72
- else:
73
- print("❌ Format non supporté :", file.filename)
74
- return None
75
- except Exception as e:
76
- print(f"❌ Erreur lors de l'extraction du texte : {e}")
77
- return None
78
-
79
- # Fonction pour résumer du texte
80
- def summarize_text(text):
81
- print(f"🔍 Texte envoyé au modèle : {text[:500]}") # Afficher les 500 premiers caractères
82
- tokens = tokenizer.tokenize(text)
83
- truncated_text = tokenizer.convert_tokens_to_string(tokens[:1024]) # Limite à 1024 tokens
84
- print(f"📏 Texte après troncature : {truncated_text[:500]}")
85
-
86
- try:
87
- summary = summarizer(truncated_text, max_length=130, min_length=30, do_sample=False)
88
- print(f"📝 Résumé généré : {summary[0]['summary_text']}")
89
- return summary[0]['summary_text']
90
- except Exception as e:
91
- print(f"❌ Erreur du modèle de résumé : {e}")
92
- return None
93
-
94
- # ✅ TEST : Extraire le texte d'un fichier
95
- @app.post("/test_extraction/")
96
- async def test_extraction(file: UploadFile = File(...)):
97
- text = extract_text_from_file(file)
98
-
99
- if not text or not text.strip():
100
- return {"error": "Aucun texte extrait du fichier"}
101
-
102
- return {"extracted_text": text[:500]} # Affichage limité à 500 caractères
103
-
104
- # ✅ TEST : Vérifier le résumé d'un texte simple
105
- @app.post("/test_summary_text/")
106
- async def test_summary_text(text: str):
107
- if not text or not text.strip():
108
- return {"error": "Texte vide"}
109
-
110
- summary = summarize_text(text)
111
- if not summary:
112
- return {"error": "Échec du résumé"}
113
-
114
- return {"summary": summary}
115
-
116
- # ✅ DEBUG : Voir toutes les étapes du résumé
117
- @app.post("/debug_summary/")
118
- async def debug_summary(text: str):
119
- if not text or not text.strip():
120
- return {"error": "Texte vide"}
121
 
122
- try:
123
- tokens = tokenizer.tokenize(text)
124
- truncated_text = tokenizer.convert_tokens_to_string(tokens[:1024])
125
- summary = summarizer(truncated_text, max_length=130, min_length=30, do_sample=False)
126
 
127
- return {
128
- "original_text": text[:500],
129
- "truncated_text": truncated_text[:500],
130
- "summary": summary[0]['summary_text']
131
- }
132
- except Exception as e:
133
- return {"error": str(e)}
134
 
135
- # 🔹 Endpoint principal : Résumer un fichier
136
- @app.post("/summarize/")
137
- async def summarize_file(file: UploadFile = File(...)):
138
- text = extract_text_from_file(file)
139
- if not text or not text.strip():
140
- return {"error": "Aucun texte extrait du fichier"}
141
-
142
- summary = summarize_text(text)
143
- if not summary:
144
- return {"error": "Échec du résumé"}
145
 
146
- return {"summary": summary}
147
 
148
- # 🔹 Endpoint : Interpréter une image
149
  @app.post("/interpret/")
150
  async def interpret_image(file: UploadFile = File(...)):
151
- image = Image.open(io.BytesIO(await file.read()))
152
- caption = image_captioner(image)
153
- return {"caption": caption[0]['generated_text']}
154
 
 
 
155
 
 
156
 
157
- if __name__ == "__main__":
158
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ from fastapi import FastAPI, File, UploadFile
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi.staticfiles import StaticFiles
4
+ from transformers import pipeline
5
+ import shutil
6
+ import os
 
 
 
 
7
 
8
  app = FastAPI()
9
 
10
+ # Servir les fichiers statiques (HTML, CSS, JS)
11
+ app.mount("/", StaticFiles(directory="static", html=True), name="static")
 
 
 
 
 
 
12
 
13
+ # Modèle Hugging Face pour le résumé de texte
14
+ summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
15
 
16
+ # Modèle Hugging Face pour l'interprétation d'images
17
+ image_captioning = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
 
 
18
 
19
+ UPLOAD_DIR = "uploads"
20
+ os.makedirs(UPLOAD_DIR, exist_ok=True)
 
 
 
 
 
21
 
22
+ @app.post("/summarize/")
23
+ async def summarize_document(file: UploadFile = File(...)):
24
+ """ Analyse et résume un document texte. """
25
+ file_path = os.path.join(UPLOAD_DIR, file.filename)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ # Sauvegarde temporaire du fichier
28
+ with open(file_path, "wb") as buffer:
29
+ shutil.copyfileobj(file.file, buffer)
 
30
 
31
+ # Lire le contenu du fichier (ex: PDF, DOCX) et l'envoyer au modèle
32
+ # Ici, je vais supposer que c'est un fichier texte brut pour simplifier
33
+ with open(file_path, "r", encoding="utf-8") as f:
34
+ text = f.read()
 
 
 
35
 
36
+ summary = summarizer(text, max_length=150, min_length=50, do_sample=False)[0]["summary_text"]
 
 
 
 
 
 
 
 
 
37
 
38
+ return JSONResponse(content={"summary": summary})
39
 
 
40
  @app.post("/interpret/")
41
  async def interpret_image(file: UploadFile = File(...)):
42
+ """ Génère une légende pour une image. """
43
+ file_path = os.path.join(UPLOAD_DIR, file.filename)
 
44
 
45
+ with open(file_path, "wb") as buffer:
46
+ shutil.copyfileobj(file.file, buffer)
47
 
48
+ caption = image_captioning(file_path)[0]["generated_text"]
49
 
50
+ return JSONResponse(content={"caption": caption})