| from fastapi import FastAPI, Request, Form |
| from fastapi.responses import HTMLResponse |
| from fastapi.templating import Jinja2Templates |
| import sys |
| import io |
|
|
| app = FastAPI() |
| templates = Jinja2Templates(directory="templates") |
|
|
| |
| def run_code_with_trace(code: str): |
| trace_data = [] |
| stdout_capture = io.StringIO() |
|
|
| def tracer(frame, event, arg): |
| if event == "line": |
| trace_data.append({ |
| "line": frame.f_lineno, |
| "locals": frame.f_locals.copy() |
| }) |
| return tracer |
|
|
| sys.settrace(tracer) |
| try: |
| exec(code, {}, {}) |
| except Exception as e: |
| trace_data.append({"error": str(e)}) |
| finally: |
| sys.settrace(None) |
|
|
| 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": trace, |
| "output": output, |
| "code": code |
| } |
| ) |
|
|