SamiKLN commited on
Commit
b03a71c
·
verified ·
1 Parent(s): 6b72d24

Delete main.py

Browse files
Files changed (1) hide show
  1. main.py +0 -271
main.py DELETED
@@ -1,271 +0,0 @@
1
- import os
2
- import uuid
3
- import logging
4
- from pathlib import Path
5
- from typing import List, Optional
6
- from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Request
7
- from fastapi.staticfiles import StaticFiles
8
- from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
9
- from fastapi.middleware.cors import CORSMiddleware
10
- from pydantic import BaseModel
11
- from huggingface_hub import InferenceClient
12
- import fitz # PyMuPDF
13
- from PIL import Image
14
- import io
15
- import pandas as pd
16
- from docx import Document
17
- from pptx import Presentation
18
-
19
- # Configuration du logging
20
- logging.basicConfig(level=logging.INFO)
21
- logger = logging.getLogger(__name__)
22
-
23
- # Initialisation de l'application FastAPI
24
- app = FastAPI()
25
-
26
- # Configuration CORS
27
- app.add_middleware(
28
- CORSMiddleware,
29
- allow_origins=["*"],
30
- allow_methods=["*"],
31
- allow_headers=["*"],
32
- )
33
-
34
- # Chemins des fichiers
35
- BASE_DIR = Path(__file__).parent
36
- UPLOAD_FOLDER = BASE_DIR / "uploads"
37
- os.makedirs(UPLOAD_FOLDER, exist_ok=True)
38
-
39
- # Modèles Hugging Face
40
- HF_TOKEN = os.getenv("HF_TOKEN")
41
- client = InferenceClient(token=HF_TOKEN)
42
- MODELS = {
43
- "summary": "facebook/bart-large-cnn",
44
- "caption": "Salesforce/blip-image-captioning-large",
45
- "qa": "deepseek-ai/DeepSeek-V2-Chat"
46
- }
47
-
48
- # Modèles Pydantic
49
- class FileInfo(BaseModel):
50
- file_id: str
51
- file_name: str
52
- file_type: str
53
- file_path: str
54
- extracted_text: Optional[str] = None
55
-
56
- class SummaryRequest(BaseModel):
57
- file_id: str
58
- max_length: int = 150
59
-
60
- class CaptionRequest(BaseModel):
61
- file_id: str
62
-
63
- class QARequest(BaseModel):
64
- file_id: Optional[str] = None
65
- question: str
66
-
67
- # Fonctions utilitaires
68
- def extract_text_from_pdf(file_path: str) -> str:
69
- try:
70
- doc = fitz.open(file_path)
71
- return "\n".join([page.get_text() for page in doc])
72
- except Exception as e:
73
- logger.error(f"PDF extraction error: {e}")
74
- raise HTTPException(400, "Erreur d'extraction PDF")
75
-
76
- def extract_text_from_docx(file_path: str) -> str:
77
- try:
78
- doc = Document(file_path)
79
- return "\n".join([para.text for para in doc.paragraphs])
80
- except Exception as e:
81
- logger.error(f"DOCX extraction error: {e}")
82
- raise HTTPException(400, "Erreur d'extraction DOCX")
83
-
84
- def extract_text_from_pptx(file_path: str) -> str:
85
- try:
86
- prs = Presentation(file_path)
87
- text = []
88
- for slide in prs.slides:
89
- for shape in slide.shapes:
90
- if hasattr(shape, "text"):
91
- text.append(shape.text)
92
- return "\n".join(text)
93
- except Exception as e:
94
- logger.error(f"PPTX extraction error: {e}")
95
- raise HTTPException(400, "Erreur d'extraction PPTX")
96
-
97
- def extract_text_from_excel(file_path: str) -> str:
98
- try:
99
- xls = pd.ExcelFile(file_path)
100
- text = []
101
- for sheet_name in xls.sheet_names:
102
- df = pd.read_excel(file_path, sheet_name=sheet_name)
103
- text.append(f"Feuille: {sheet_name}\n{df.to_string()}")
104
- return "\n\n".join(text)
105
- except Exception as e:
106
- logger.error(f"Excel extraction error: {e}")
107
- raise HTTPException(400, "Erreur d'extraction Excel")
108
-
109
- async def process_uploaded_file(file: UploadFile) -> FileInfo:
110
- file_ext = Path(file.filename).suffix.lower()
111
- file_id = str(uuid.uuid4())
112
- file_path = str(UPLOAD_FOLDER / f"{file_id}{file_ext}")
113
-
114
- # Sauvegarde du fichier
115
- with open(file_path, "wb") as buffer:
116
- buffer.write(await file.read())
117
-
118
- # Extraction du texte selon le type de fichier
119
- text = ""
120
- if file_ext == ".pdf":
121
- text = extract_text_from_pdf(file_path)
122
- elif file_ext == ".docx":
123
- text = extract_text_from_docx(file_path)
124
- elif file_ext == ".pptx":
125
- text = extract_text_from_pptx(file_path)
126
- elif file_ext in (".xlsx", ".xls"):
127
- text = extract_text_from_excel(file_path)
128
-
129
- return FileInfo(
130
- file_id=file_id,
131
- file_name=file.filename,
132
- file_type=file_ext[1:],
133
- file_path=file_path,
134
- extracted_text=text if text else None
135
- )
136
-
137
- # Configuration des fichiers statiques
138
- app.mount("/", StaticFiles(directory=BASE_DIR, html=True), name="static")
139
-
140
- # Endpoints
141
- @app.get("/api", response_class=HTMLResponse)
142
- async def home():
143
- return FileResponse(BASE_DIR / "index.html")
144
-
145
- @app.post("/api/upload", response_model=List[FileInfo])
146
- async def upload_files(files: List[UploadFile] = File(...)):
147
- try:
148
- processed_files = []
149
- for file in files:
150
- processed_file = await process_uploaded_file(file)
151
- processed_files.append(processed_file)
152
- return processed_files
153
- except Exception as e:
154
- logger.error(f"Upload error: {e}")
155
- raise HTTPException(500, f"Erreur lors de l'upload: {str(e)}")
156
-
157
- @app.post("/api/summarize")
158
- async def summarize_document(request: SummaryRequest):
159
- try:
160
- file_path = next(f for f in UPLOAD_FOLDER.glob(f"{request.file_id}*"))
161
- text = ""
162
-
163
- if file_path.suffix == ".pdf":
164
- text = extract_text_from_pdf(str(file_path))
165
- else:
166
- with open(file_path, "r", encoding="utf-8") as f:
167
- text = f.read()
168
-
169
- prompt = f"""
170
- Résumez ce document de manière concise en français.
171
- Concentrez-vous sur les points principaux.
172
- Le résumé doit faire environ {request.max_length} mots.
173
-
174
- Document:
175
- {text[:5000]}... [truncated]
176
- """
177
-
178
- summary = client.summarization(
179
- text=text,
180
- model=MODELS["summary"],
181
- parameters={"max_length": request.max_length}
182
- )
183
-
184
- return {"summary": summary}
185
- except Exception as e:
186
- logger.error(f"Summarization error: {e}")
187
- raise HTTPException(500, f"Erreur de résumé: {str(e)}")
188
-
189
- @app.post("/api/caption")
190
- async def caption_image(request: CaptionRequest):
191
- try:
192
- file_path = next(f for f in UPLOAD_FOLDER.glob(f"{request.file_id}*"))
193
-
194
- with open(file_path, "rb") as image_file:
195
- image_data = image_file.read()
196
-
197
- caption = client.image_to_text(
198
- image=image_data,
199
- model=MODELS["caption"]
200
- )
201
-
202
- return {"caption": caption}
203
- except Exception as e:
204
- logger.error(f"Captioning error: {e}")
205
- raise HTTPException(500, f"Erreur de description: {str(e)}")
206
-
207
- @app.post("/api/answer")
208
- async def answer_question(request: QARequest):
209
- try:
210
- context = ""
211
- if request.file_id:
212
- file_path = next(f for f in UPLOAD_FOLDER.glob(f"{request.file_id}*"))
213
-
214
- if file_path.suffix in (".jpg", ".jpeg", ".png"):
215
- with open(file_path, "rb") as image_file:
216
- image_data = image_file.read()
217
- context = client.image_to_text(image=image_data, model=MODELS["caption"])
218
- else:
219
- if file_path.suffix == ".pdf":
220
- context = extract_text_from_pdf(str(file_path))
221
- else:
222
- with open(file_path, "r", encoding="utf-8") as f:
223
- context = f.read()
224
-
225
- prompt = f"""
226
- Vous êtes un assistant IA qui répond à des questions en français.
227
- Répondez de manière précise et concise.
228
- Contexte: {context[:3000]}
229
- Question: {request.question}
230
- Réponse:
231
- """
232
-
233
- response = client.chat_completion(
234
- model=MODELS["qa"],
235
- messages=[{"role": "user", "content": prompt}],
236
- max_tokens=500
237
- )
238
-
239
- return {"answer": response.choices[0].message.content}
240
- except Exception as e:
241
- logger.error(f"QA error: {e}")
242
- raise HTTPException(500, f"Erreur de réponse: {str(e)}")
243
-
244
- @app.get("/api/file/{file_id}")
245
- async def get_file(file_id: str):
246
- try:
247
- file_path = next(f for f in UPLOAD_FOLDER.glob(f"{file_id}*"))
248
- return FileResponse(file_path)
249
- except Exception as e:
250
- logger.error(f"File retrieval error: {e}")
251
- raise HTTPException(404, "Fichier non trouvé")
252
-
253
- # Gestion des erreurs
254
- @app.exception_handler(HTTPException)
255
- async def http_exception_handler(request, exc):
256
- return JSONResponse(
257
- status_code=exc.status_code,
258
- content={"detail": exc.detail},
259
- )
260
-
261
- @app.exception_handler(Exception)
262
- async def generic_exception_handler(request, exc):
263
- logger.error(f"Unhandled exception: {exc}")
264
- return JSONResponse(
265
- status_code=500,
266
- content={"detail": "Une erreur interne est survenue"},
267
- )
268
-
269
- if __name__ == "__main__":
270
- import uvicorn
271
- uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)