SPB Git forge

spb/uqo-chat

Public
14commits 1branches 0releases
1.4 MBsize
maindefault branch
17 days agolast push
Python 64.6% TypeScript 33.7% CSS 0.8%
1.2 KB · 40 lines python
Raw Blame History
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