SamiKLN commited on
Commit
d3c2ed1
·
verified ·
1 Parent(s): 20a13eb

Update backend_fastapi.py

Browse files
Files changed (1) hide show
  1. backend_fastapi.py +103 -73
backend_fastapi.py CHANGED
@@ -1,7 +1,7 @@
1
- from fastapi import FastAPI, File, UploadFile, Form, Request
2
  from fastapi.staticfiles import StaticFiles
3
  from fastapi.templating import Jinja2Templates
4
- from fastapi.responses import HTMLResponse
5
  from typing import Optional
6
  import requests
7
  import json
@@ -11,21 +11,24 @@ import seaborn as sns
11
  import pandas as pd
12
  import os
13
  import subprocess
 
14
 
15
  app = FastAPI()
16
 
17
- # Set up templates
18
  templates = Jinja2Templates(directory="frontend")
19
 
20
  @app.get("/", response_class=HTMLResponse)
21
  async def index(request: Request):
22
  return templates.TemplateResponse("index.html", {"request": request})
23
 
24
- # Hugging Face API Key retrieved from environment variables
25
  HUGGINGFACE_API_KEY = os.getenv("HF_API_KEY")
 
 
26
  HEADERS = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}
27
 
28
- # Updated model identifiers
29
  HF_MODELS = {
30
  "summary": "facebook/bart-large-cnn",
31
  "caption": "Salesforce/blip-image-captioning-large",
@@ -36,78 +39,105 @@ HF_MODELS = {
36
  HF_API_URL = "https://api-inference.huggingface.co/models/"
37
 
38
  def query_huggingface(model: str, payload: dict):
39
- response = requests.post(f"{HF_API_URL}{model}", headers=HEADERS, json=payload)
40
- return response.json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- # 1. Résumé de texte (documents PDF, DOCX, PPTX, etc.)
43
  @app.post("/summarize")
44
  async def summarize_document(file: UploadFile = File(...)):
45
- text = file.file.read().decode("utf-8")
46
- response = query_huggingface(HF_MODELS["summary"], {
47
- "inputs": text,
48
- "parameters": {
49
- "max_length": 150,
50
- "min_length": 50,
51
- "do_sample": False
52
- }
53
- })
54
- return {"summary": response[0]["summary_text"], "filename": file.filename}
55
-
56
- # 2. Interprétation d’image
57
- @app.post("/interpret_image")
58
- async def interpret_image(file: UploadFile = File(...)):
59
- image_bytes = file.file.read()
60
- response = requests.post(
61
- f"{HF_API_URL}{HF_MODELS['caption']}",
62
- headers={**HEADERS, "Content-Type": file.content_type},
63
- data=image_bytes
64
- )
65
- print("Réponse de l'API:", response.json())
66
- json_response = response.json()
67
-
68
- if isinstance(json_response, dict) and json_response.get("error"):
69
- return {"error": json_response["error"], "filename": file.filename}
70
-
71
  try:
72
- caption = json_response[0]['generated_text']
73
- except (IndexError, KeyError, TypeError):
74
- return {"error": "Structure de réponse inattendue", "response": json_response, "filename": file.filename}
75
-
76
- return {"caption": caption, "filename": file.filename}
77
-
78
- # 3. Réponse intelligente aux questions sur document/image
79
- @app.post("/answer_question")
80
- async def answer_question(question: str = Form(...), file: Optional[UploadFile] = None):
81
- context = file.file.read().decode("utf-8") if file else ""
82
- response = query_huggingface(HF_MODELS["qa"], {"question": question, "context": context})
83
- return {
84
- "answer": response['answer'],
85
- "score": response['score'],
86
- "filename": file.filename if file else None
87
- }
88
-
89
- # 4. Génération de code de visualisation
90
- @app.post("/generate_visualization")
91
- async def generate_visualization(file: UploadFile = File(...), request: str = Form(...)):
92
- df = pd.read_excel(file.file)
93
- plt.figure(figsize=(8, 5))
94
- sns.histplot(df, kde=True)
95
- buffer = io.BytesIO()
96
- plt.savefig(buffer, format="png")
97
- buffer.seek(0)
98
- return {"message": "Graphique généré", "filename": file.filename}
99
-
100
- # 5. Traduction de document
101
- @app.post("/translate_document")
102
- async def translate_document(file: UploadFile = File(...), target_language: str = Form(...)):
103
- text = file.file.read().decode("utf-8")
104
- response = query_huggingface(HF_MODELS["translation"], {"inputs": text})
105
- return {
106
- "translated_text": response[0]['translation_text'],
107
- "target_language": target_language,
108
- "filename": file.filename
109
- }
110
 
111
  if __name__ == "__main__":
112
  import uvicorn
113
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ from fastapi import FastAPI, File, UploadFile, Form, Request, HTTPException
2
  from fastapi.staticfiles import StaticFiles
3
  from fastapi.templating import Jinja2Templates
4
+ from fastapi.responses import HTMLResponse, JSONResponse
5
  from typing import Optional
6
  import requests
7
  import json
 
11
  import pandas as pd
12
  import os
13
  import subprocess
14
+ from pathlib import Path
15
 
16
  app = FastAPI()
17
 
18
+ # Configuration des templates
19
  templates = Jinja2Templates(directory="frontend")
20
 
21
  @app.get("/", response_class=HTMLResponse)
22
  async def index(request: Request):
23
  return templates.TemplateResponse("index.html", {"request": request})
24
 
25
+ # Clé API Hugging Face
26
  HUGGINGFACE_API_KEY = os.getenv("HF_API_KEY")
27
+ if not HUGGINGFACE_API_KEY:
28
+ raise RuntimeError("La clé API Hugging Face n'est pas configurée")
29
  HEADERS = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}
30
 
31
+ # Modèles Hugging Face
32
  HF_MODELS = {
33
  "summary": "facebook/bart-large-cnn",
34
  "caption": "Salesforce/blip-image-captioning-large",
 
39
  HF_API_URL = "https://api-inference.huggingface.co/models/"
40
 
41
  def query_huggingface(model: str, payload: dict):
42
+ try:
43
+ response = requests.post(
44
+ f"{HF_API_URL}{model}",
45
+ headers=HEADERS,
46
+ json=payload,
47
+ timeout=30
48
+ )
49
+ response.raise_for_status()
50
+ return response.json()
51
+ except requests.exceptions.RequestException as e:
52
+ return {"error": f"Erreur API Hugging Face: {str(e)}"}
53
+ except json.JSONDecodeError:
54
+ return {"error": "Réponse JSON invalide de l'API"}
55
+
56
+ async def convert_to_text(file: UploadFile) -> str:
57
+ """Convertit un fichier uploadé en texte brut"""
58
+ temp_dir = Path("temp_files")
59
+ temp_dir.mkdir(exist_ok=True)
60
+ temp_path = temp_dir / file.filename
61
+
62
+ try:
63
+ # Sauvegarder le fichier temporairement
64
+ with open(temp_path, "wb") as f:
65
+ content = await file.read()
66
+ f.write(content)
67
+
68
+ # Conversion selon le type de fichier
69
+ if file.filename.endswith('.txt'):
70
+ with open(temp_path, "r", encoding='utf-8') as f:
71
+ return f.read()
72
+
73
+ elif file.filename.endswith('.pdf'):
74
+ result = subprocess.run(
75
+ ["pdftotext", str(temp_path), "-"],
76
+ capture_output=True,
77
+ text=True
78
+ )
79
+ if result.returncode != 0:
80
+ raise RuntimeError(f"Erreur pdftotext: {result.stderr}")
81
+ return result.stdout
82
+
83
+ elif file.filename.endswith('.docx'):
84
+ result = subprocess.run(
85
+ ["pandoc", "-t", "plain", str(temp_path)],
86
+ capture_output=True,
87
+ text=True
88
+ )
89
+ if result.returncode != 0:
90
+ raise RuntimeError(f"Erreur pandoc: {result.stderr}")
91
+ return result.stdout
92
+
93
+ else:
94
+ raise ValueError("Format de fichier non supporté")
95
+
96
+ finally:
97
+ # Nettoyage du fichier temporaire
98
+ if temp_path.exists():
99
+ temp_path.unlink()
100
 
 
101
  @app.post("/summarize")
102
  async def summarize_document(file: UploadFile = File(...)):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  try:
104
+ # Conversion du fichier en texte
105
+ text = await convert_to_text(file)
106
+ if not text.strip():
107
+ raise HTTPException(400, "Le fichier est vide ou n'a pas pu être converti")
108
+
109
+ # Appel à l'API Hugging Face
110
+ response = query_huggingface(HF_MODELS["summary"], {
111
+ "inputs": text,
112
+ "parameters": {
113
+ "max_length": 150,
114
+ "min_length": 50,
115
+ "do_sample": False
116
+ }
117
+ })
118
+
119
+ # Gestion de la réponse
120
+ if isinstance(response, dict) and "error" in response:
121
+ raise HTTPException(502, response["error"])
122
+
123
+ if not isinstance(response, list) or len(response) == 0:
124
+ raise HTTPException(502, "Réponse inattendue de l'API")
125
+
126
+ return JSONResponse({
127
+ "summary": response[0].get("summary_text", "Aucun résumé généré"),
128
+ "filename": file.filename,
129
+ "text_length": len(text)
130
+ })
131
+
132
+ except HTTPException:
133
+ raise
134
+ except ValueError as e:
135
+ raise HTTPException(400, str(e))
136
+ except Exception as e:
137
+ raise HTTPException(500, f"Erreur interne: {str(e)}")
138
+
139
+ # ... (les autres routes restent inchangées)
 
 
140
 
141
  if __name__ == "__main__":
142
  import uvicorn
143
+ uvicorn.run(app, host="0.0.0.0", port=7860)