Spaces:
Running
Running
add
Browse files
app.py
CHANGED
|
@@ -197,8 +197,8 @@ async def generate_viz(file: UploadFile = File(...), query: str = Form(...)):
|
|
| 197 |
if query not in VALID_PLOTS:
|
| 198 |
return JSONResponse(content={"error": f"Type de graphique invalide. Choisissez parmi : {', '.join(VALID_PLOTS)}"}, status_code=400)
|
| 199 |
|
| 200 |
-
file_content = await file.read()
|
| 201 |
-
df = pd.read_excel(BytesIO(file_content))
|
| 202 |
numeric_cols = df.select_dtypes(include=["number"]).columns
|
| 203 |
|
| 204 |
if len(numeric_cols) < 1:
|
|
@@ -206,22 +206,16 @@ async def generate_viz(file: UploadFile = File(...), query: str = Form(...)):
|
|
| 206 |
|
| 207 |
x_col = numeric_cols[0]
|
| 208 |
y_col = numeric_cols[1] if query != "histplot" and len(numeric_cols) > 1 else None
|
| 209 |
-
prompt_y = f', y="{y_col}"' if y_col else ""
|
| 210 |
|
| 211 |
-
#
|
| 212 |
prompt = f"""
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
import seaborn as sns
|
| 221 |
-
plt.figure(figsize=(8,6))
|
| 222 |
-
sns.{query}(data=df, x="{x_col}"{prompt_y})
|
| 223 |
-
plt.savefig("plot.png")
|
| 224 |
-
plt.close()
|
| 225 |
"""
|
| 226 |
|
| 227 |
print("🟣 Prompt envoyé au modèle :")
|
|
@@ -234,28 +228,25 @@ plt.close()
|
|
| 234 |
pad_token_id=codegen_tokenizer.eos_token_id
|
| 235 |
)
|
| 236 |
|
| 237 |
-
print("🟠 Raw output du modèle :")
|
| 238 |
-
print(outputs)
|
| 239 |
-
|
| 240 |
generated_code = codegen_tokenizer.decode(outputs[0], skip_special_tokens=True).strip()
|
| 241 |
|
| 242 |
-
# Nettoyage
|
| 243 |
generated_code = re.sub(r"(import matplotlib.pyplot as plt\nimport seaborn as sns\n)+", "import matplotlib.pyplot as plt\nimport seaborn as sns\n", generated_code)
|
| 244 |
-
generated_code = generated_code.
|
| 245 |
-
|
| 246 |
-
if generated_code.strip().endswith("sns.") or len(generated_code.strip()) < 20:
|
| 247 |
-
return JSONResponse(content={"error": "Erreur : Code généré invalide ou incomplet."}, status_code=500)
|
| 248 |
|
| 249 |
print("🔵 Code généré propre :")
|
| 250 |
print(generated_code)
|
| 251 |
|
|
|
|
|
|
|
|
|
|
| 252 |
try:
|
| 253 |
compile(generated_code, "<string>", "exec")
|
| 254 |
except SyntaxError as e:
|
| 255 |
return JSONResponse(content={"error": f"Erreur de syntaxe détectée : {e}\nCode généré :\n{generated_code}"}, status_code=422)
|
| 256 |
|
|
|
|
| 257 |
exec_env = {"df": df, "plt": plt, "sns": sns, "pd": pd}
|
| 258 |
-
print("🔹🔹🔹 Code réellement exécuté :")
|
| 259 |
exec(generated_code, exec_env)
|
| 260 |
|
| 261 |
img_path = "plot.png"
|
|
@@ -277,7 +268,6 @@ plt.close()
|
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
-
|
| 281 |
# Charger le modèle de résumé
|
| 282 |
summarizer = None
|
| 283 |
try:
|
|
|
|
| 197 |
if query not in VALID_PLOTS:
|
| 198 |
return JSONResponse(content={"error": f"Type de graphique invalide. Choisissez parmi : {', '.join(VALID_PLOTS)}"}, status_code=400)
|
| 199 |
|
| 200 |
+
file_content = await file.read()
|
| 201 |
+
df = pd.read_excel(BytesIO(file_content))
|
| 202 |
numeric_cols = df.select_dtypes(include=["number"]).columns
|
| 203 |
|
| 204 |
if len(numeric_cols) < 1:
|
|
|
|
| 206 |
|
| 207 |
x_col = numeric_cols[0]
|
| 208 |
y_col = numeric_cols[1] if query != "histplot" and len(numeric_cols) > 1 else None
|
|
|
|
| 209 |
|
| 210 |
+
# ✅ Nouveau prompt (uniquement des instructions)
|
| 211 |
prompt = f"""
|
| 212 |
+
Génère uniquement du code Python fonctionnel pour tracer un {query} avec Matplotlib et Seaborn.
|
| 213 |
+
Contraintes :
|
| 214 |
+
- Utilise 'df' sans recréer de nouvelles données
|
| 215 |
+
- Axe X : '{x_col}'
|
| 216 |
+
- {f"Axe Y : '{y_col}'" if y_col else ''}
|
| 217 |
+
- Enregistre le graphique sous 'plot.png'
|
| 218 |
+
- Ne génère que du code Python valide, sans texte explicatif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
"""
|
| 220 |
|
| 221 |
print("🟣 Prompt envoyé au modèle :")
|
|
|
|
| 228 |
pad_token_id=codegen_tokenizer.eos_token_id
|
| 229 |
)
|
| 230 |
|
|
|
|
|
|
|
|
|
|
| 231 |
generated_code = codegen_tokenizer.decode(outputs[0], skip_special_tokens=True).strip()
|
| 232 |
|
| 233 |
+
# Nettoyage de sécurité
|
| 234 |
generated_code = re.sub(r"(import matplotlib.pyplot as plt\nimport seaborn as sns\n)+", "import matplotlib.pyplot as plt\nimport seaborn as sns\n", generated_code)
|
| 235 |
+
generated_code = generated_code.strip()
|
|
|
|
|
|
|
|
|
|
| 236 |
|
| 237 |
print("🔵 Code généré propre :")
|
| 238 |
print(generated_code)
|
| 239 |
|
| 240 |
+
if not generated_code or len(generated_code.splitlines()) < 3:
|
| 241 |
+
return JSONResponse(content={"error": "Erreur : Code généré invalide ou incomplet."}, status_code=500)
|
| 242 |
+
|
| 243 |
try:
|
| 244 |
compile(generated_code, "<string>", "exec")
|
| 245 |
except SyntaxError as e:
|
| 246 |
return JSONResponse(content={"error": f"Erreur de syntaxe détectée : {e}\nCode généré :\n{generated_code}"}, status_code=422)
|
| 247 |
|
| 248 |
+
# 🛡️ Exécution dans environnement contrôlé
|
| 249 |
exec_env = {"df": df, "plt": plt, "sns": sns, "pd": pd}
|
|
|
|
| 250 |
exec(generated_code, exec_env)
|
| 251 |
|
| 252 |
img_path = "plot.png"
|
|
|
|
| 268 |
|
| 269 |
|
| 270 |
|
|
|
|
| 271 |
# Charger le modèle de résumé
|
| 272 |
summarizer = None
|
| 273 |
try:
|