rabiyulfahim's picture
Update app.py
0944f07 verified
raw
history blame
2.06 kB
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
}
)