rabiyulfahim's picture
Update app.py
0944f07 verified
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import sys
import io
import json
app = FastAPI()
# Mount static files (for CSS, JS)
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
def run_code_with_trace(code: str):
trace_data = []
stdout_capture = io.StringIO()
# ✅ Safely serialize objects (avoid JSON TypeError)
def safe_serialize(obj):
try:
json.dumps(obj)
return obj
except (TypeError, OverflowError):
return str(obj)
# ✅ Tracer function
def tracer(frame, event, arg):
if event == "line":
locals_serialized = {k: safe_serialize(v) for k, v in frame.f_locals.items()}
trace_data.append({
"line": frame.f_lineno,
"locals": locals_serialized
})
return tracer
# Redirect stdout temporarily (if user uses print)
sys.settrace(tracer)
sys.stdout = stdout_capture
try:
safe_globals = {"__builtins__": {"print": print, "range": range, "len": len}}
exec(code, safe_globals)
except Exception as e:
trace_data.append({"error": str(e)})
finally:
sys.settrace(None)
sys.stdout = sys.__stdout__ # reset stdout
output = stdout_capture.getvalue()
stdout_capture.close()
return trace_data, output
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/run", response_class=HTMLResponse)
async def run_code(request: Request, code: str = Form(...)):
trace, output = run_code_with_trace(code)
return templates.TemplateResponse(
"index.html",
{
"request": request,
"trace_json": json.dumps(trace),
"output": output,
"code": code
}
)