Python 64.6%
TypeScript 33.7%
CSS 0.8%
1"""sandbox-runner: tiny internal HTTP service. POST /run {code, files_in, timeout_s}."""23from __future__ import annotations45import asyncio6import os7from concurrent.futures import ThreadPoolExecutor89from fastapi import FastAPI, Header, HTTPException10from pydantic import BaseModel, Field1112from runner import run1314TOKEN = os.environ.get("SANDBOX_TOKEN", "")15MAX_PARALLEL = int(os.environ.get("SANDBOX_MAX_PARALLEL", "4"))1617app = FastAPI(title="uqo-chat sandbox-runner", docs_url=None, redoc_url=None)18pool = ThreadPoolExecutor(max_workers=MAX_PARALLEL)19sem = asyncio.Semaphore(MAX_PARALLEL)202122class RunReq(BaseModel):23 code: str = Field(..., max_length=200_000)24 files_in: list[dict] = Field(default_factory=list)25 timeout_s: int = Field(30, ge=1, le=60)262728@app.get("/healthz")29async def healthz() -> dict:30 return {"ok": True}313233@app.post("/run")34async def run_code(req: RunReq, authorization: str | None = Header(default=None)) -> dict:35 if TOKEN and authorization != f"Bearer {TOKEN}":36 raise HTTPException(401, "unauthorized")37 async with sem:38 loop = asyncio.get_running_loop()39 return await loop.run_in_executor(pool, run, req.code, req.files_in, req.timeout_s)40