AxL95 commited on
Commit
540ce5d
·
verified ·
1 Parent(s): ab0cc14

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -3
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import FastAPI, Request, HTTPException,Depends, Response
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import JSONResponse
4
  from fastapi.staticfiles import StaticFiles
@@ -15,6 +15,9 @@ import os
15
  from pymongo import MongoClient
16
  from datetime import datetime
17
  from passlib.hash import bcrypt
 
 
 
18
 
19
  SECRET_KEY = secrets.token_hex(32)
20
 
@@ -53,6 +56,153 @@ app.add_middleware(
53
  )
54
 
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  @app.post("/api/login")
58
  async def login(request: Request, response: Response):
@@ -95,7 +245,9 @@ async def login(request: Request, response: Response):
95
  "success": True,
96
  "username": username,
97
  "user_id": user_id,
98
- "session_id": session_id
 
 
99
  }
100
 
101
  except Exception as e:
@@ -165,7 +317,9 @@ async def register(request: Request):
165
  "nom": data["nom"],
166
  "email": data["email"],
167
  "password": hashed_password,
168
- "createdAt": datetime.utcnow()
 
 
169
  }
170
 
171
  result = db.users.insert_one(user)
 
1
+ from fastapi import FastAPI, Request, HTTPException,Depends,File, UploadFile, Response
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import JSONResponse
4
  from fastapi.staticfiles import StaticFiles
 
15
  from pymongo import MongoClient
16
  from datetime import datetime
17
  from passlib.hash import bcrypt
18
+ import PyPDF2
19
+ from io import BytesIO
20
+ import uuid
21
 
22
  SECRET_KEY = secrets.token_hex(32)
23
 
 
56
  )
57
 
58
 
59
+ async def get_admin_user(request: Request):
60
+ user = await get_current_user(request)
61
+ if user["role"] != "Administrateur":
62
+ raise HTTPException(status_code=403, detail="Accès interdit: Droits d'administrateur requis")
63
+ return user
64
+
65
+
66
+ # Initialiser le modèle d'embedding (à faire une seule fois au démarrage)
67
+ try:
68
+ embedder = SentenceTransformer('all-MiniLM-L6-v2')
69
+ except Exception as e:
70
+ print(f"Erreur lors du chargement du modèle d'embedding: {str(e)}")
71
+ embedder = None
72
+ @app.post("/api/admin/knowledge/upload")
73
+ async def upload_pdf(
74
+ file: UploadFile = File(...),
75
+ title: str = None,
76
+ tags: str = None,
77
+ current_user: dict = Depends(get_admin_user)
78
+ ):
79
+ try:
80
+ # Vérifier que le fichier est un PDF
81
+ if not file.filename.endswith('.pdf'):
82
+ raise HTTPException(status_code=400, detail="Le fichier doit être un PDF")
83
+
84
+ # Lire le contenu du PDF
85
+ contents = await file.read()
86
+ pdf_file = BytesIO(contents)
87
+
88
+ # Extraire le texte du PDF
89
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
90
+ text_content = ""
91
+ for page_num in range(len(pdf_reader.pages)):
92
+ text_content += pdf_reader.pages[page_num].extract_text() + "\n"
93
+
94
+ # Générer un embedding pour l'ensemble du texte si le modèle est disponible
95
+ embedding = None
96
+ if embedder:
97
+ try:
98
+ # Limiter la taille du texte si nécessaire
99
+ max_length = 5000
100
+ truncated_text = text_content[:max_length]
101
+ embedding = embedder.encode(truncated_text).tolist()
102
+ except Exception as e:
103
+ print(f"Erreur lors de la génération de l'embedding: {str(e)}")
104
+
105
+ # Générer un identifiant unique pour le document
106
+ doc_id = ObjectId()
107
+
108
+ # Enregistrer le fichier original
109
+ pdf_path = f"files/{str(doc_id)}.pdf"
110
+ os.makedirs("files", exist_ok=True)
111
+ with open(pdf_path, "wb") as f:
112
+ pdf_file.seek(0)
113
+ f.write(contents)
114
+
115
+ # Créer un objet document dans MongoDB
116
+ document = {
117
+ "_id": doc_id,
118
+ "text": text_content,
119
+ "embedding": embedding,
120
+ "title": title or file.filename,
121
+ "tags": tags.split(",") if tags else [],
122
+ "uploaded_by": str(current_user["_id"]),
123
+ "upload_date": datetime.utcnow()
124
+ }
125
+
126
+ print(f"Tentative d'insertion du document avec ID: {doc_id}")
127
+ result = db.connaissances.insert_one(document)
128
+ print(f"Document inséré avec ID: {result.inserted_id}")
129
+
130
+ # Vérification de l'insertion
131
+ verification = db.connaissances.find_one({"_id": doc_id})
132
+ if verification:
133
+ print(f"Document vérifié et trouvé dans la base de données")
134
+ return {"success": True, "document_id": str(doc_id)}
135
+ else:
136
+ print(f"ERREUR: Document non trouvé après insertion")
137
+ return {"success": False, "error": "Document non trouvé après insertion"}
138
+
139
+ except Exception as e:
140
+ import traceback
141
+ print(f"Erreur lors de l'upload du PDF: {traceback.format_exc()}")
142
+ raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
143
+
144
+ @app.get("/api/admin/knowledge")
145
+ async def list_documents(current_user: dict = Depends(get_admin_user)):
146
+ try:
147
+ # Récupérer les documents triés par date (plus récents en premier)
148
+ documents = list(db.connaissances.find().sort("upload_date", -1))
149
+
150
+ # Convertir les types non sérialisables (ObjectId, datetime, etc.)
151
+ result = []
152
+ for doc in documents:
153
+ doc_safe = {
154
+ "id": str(doc["_id"]),
155
+ "title": doc.get("title", "Sans titre"),
156
+ "tags": doc.get("tags", []),
157
+ "date": doc.get("upload_date").isoformat() if "upload_date" in doc else None,
158
+ "text_preview": doc.get("text", "")[:100] + "..." if len(doc.get("text", "")) > 100 else doc.get("text", "")
159
+ }
160
+ result.append(doc_safe)
161
+
162
+ return {"documents": result}
163
+ except Exception as e:
164
+ print(f"Erreur lors de la liste des documents: {str(e)}")
165
+ raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
166
+
167
+
168
+
169
+ @app.delete("/api/admin/knowledge/{document_id}")
170
+ async def delete_document(document_id: str, current_user: dict = Depends(get_admin_user)):
171
+ try:
172
+ # Convertir l'ID string en ObjectId
173
+ try:
174
+ doc_id = ObjectId(document_id)
175
+ except Exception:
176
+ raise HTTPException(status_code=400, detail="ID de document invalide")
177
+
178
+ # Vérifier si le document existe
179
+ document = db.connaissances.find_one({"_id": doc_id})
180
+ if not document:
181
+ raise HTTPException(status_code=404, detail="Document non trouvé")
182
+
183
+ # Supprimer le document de la base de données
184
+ result = db.connaissances.delete_one({"_id": doc_id})
185
+
186
+ if result.deleted_count == 0:
187
+ raise HTTPException(status_code=500, detail="Échec de la suppression du document")
188
+
189
+ # Supprimer le fichier PDF associé s'il existe
190
+ pdf_path = f"files/{document_id}.pdf"
191
+ if os.path.exists(pdf_path):
192
+ try:
193
+ os.remove(pdf_path)
194
+ print(f"Fichier supprimé: {pdf_path}")
195
+ except Exception as e:
196
+ print(f"Erreur lors de la suppression du fichier: {str(e)}")
197
+ # On continue même si la suppression du fichier échoue
198
+
199
+ return {"success": True, "message": "Document supprimé avec succès"}
200
+
201
+ except HTTPException as he:
202
+ raise he
203
+ except Exception as e:
204
+ raise HTTPException(status_code=500, detail=f"Erreur lors de la suppression: {str(e)}")
205
+
206
 
207
  @app.post("/api/login")
208
  async def login(request: Request, response: Response):
 
245
  "success": True,
246
  "username": username,
247
  "user_id": user_id,
248
+ "session_id": session_id,
249
+ "role": user.get("role", "user")
250
+
251
  }
252
 
253
  except Exception as e:
 
317
  "nom": data["nom"],
318
  "email": data["email"],
319
  "password": hashed_password,
320
+ "createdAt": datetime.utcnow(),
321
+ "role": data.get("role", "user"),
322
+
323
  }
324
 
325
  result = db.users.insert_one(user)