Cyrano2's picture
Update app.py
b3c128e verified
"""
MimiReady Python Executor Backend
Exécute du code Python avec TensorFlow/Keras sur Hugging Face Spaces
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Optional
import sys
import io
import base64
import traceback
from contextlib import redirect_stdout, redirect_stderr
# Configuration matplotlib avant import
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
app = FastAPI(title="MimiReady Python Executor")
# CORS pour permettre les requêtes depuis le frontend
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class CodeRequest(BaseModel):
code: str
timeout: int = 30
class CodeResponse(BaseModel):
stdout: str
stderr: str
plots: List[str]
success: bool
error: Optional[str] = None
# Variables globales pour capturer les plots
_plot_images: List[str] = []
def capture_plots():
"""Capture tous les plots matplotlib en base64"""
global _plot_images
_plot_images = []
original_show = plt.show
def patched_show(*args, **kwargs):
global _plot_images
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=100, bbox_inches='tight', facecolor='white')
buf.seek(0)
img_str = base64.b64encode(buf.read()).decode('utf-8')
_plot_images.append(img_str)
plt.clf()
plt.close('all')
plt.show = patched_show
return original_show
def restore_show(original_show):
"""Restaure plt.show original"""
plt.show = original_show
@app.get("/")
def read_root():
return {
"service": "MimiReady Python Executor",
"status": "running",
"capabilities": ["numpy", "pandas", "matplotlib", "scikit-learn", "tensorflow", "keras"]
}
@app.get("/health")
def health_check():
return {"status": "healthy"}
@app.post("/execute", response_model=CodeResponse)
async def execute_code(request: CodeRequest):
"""Exécute du code Python et retourne les résultats"""
global _plot_images
stdout_capture = io.StringIO()
stderr_capture = io.StringIO()
# Préparer l'environnement d'exécution
exec_globals = {
"__builtins__": __builtins__,
"__name__": "__main__",
}
# Pre-import des bibliothèques courantes
try:
import numpy as np
exec_globals["np"] = np
exec_globals["numpy"] = np
except ImportError:
pass
try:
import pandas as pd
exec_globals["pd"] = pd
exec_globals["pandas"] = pd
except ImportError:
pass
try:
import sklearn
exec_globals["sklearn"] = sklearn
except ImportError:
pass
# TensorFlow/Keras
try:
import tensorflow as tf
from tensorflow import keras
exec_globals["tf"] = tf
exec_globals["tensorflow"] = tf
exec_globals["keras"] = keras
except ImportError as e:
print(f"TensorFlow import warning: {e}")
# Matplotlib
exec_globals["plt"] = plt
exec_globals["matplotlib"] = matplotlib
success = True
error_msg = None
original_show = capture_plots()
try:
with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture):
exec(request.code, exec_globals)
except Exception as e:
success = False
error_msg = f"{type(e).__name__}: {str(e)}\n{traceback.format_exc()}"
finally:
restore_show(original_show)
return CodeResponse(
stdout=stdout_capture.getvalue(),
stderr=stderr_capture.getvalue(),
plots=_plot_images.copy(),
success=success,
error=error_msg
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)