Model writes code
Your LLM returns a Python snippet as its tool call — a pandas transform, a plot, a quick calculation.
Give your model a real Python runtime it can write into and read back. Spin up a code-interpreter sandbox, upload data, run model-written pandas, and feed r.stdout back into the next turn — in under ten lines.
pandas & matplotlib baked in · per-second billing · E2B_API_KEY works too.
# pip install pilldrops from pilldrops import Sandbox with Sandbox.create(template="code-interpreter") as sb: sb.upload("./sales.csv", "/data/sales.csv") r = sb.run("python -c \"import pandas as pd; print(pd.read_csv('/data/sales.csv').revenue.sum())\"") print(r.stdout) # 48210.75
// npm i @pilldrops/sdk import { Sandbox } from '@pilldrops/sdk' const sb = await Sandbox.create({ template: 'code-interpreter' }) await sb.upload('./sales.csv', '/data/sales.csv') const r = await sb.run("python -c \"import pandas as pd; print(pd.read_csv('/data/sales.csv').revenue.sum())\"") console.log(r.stdout) // 48210.75 await sb.kill()
# 1. create a code-interpreter sandbox $ curl -X POST https://pilldrops.com/v1/sandboxes \ -H "Authorization: Bearer $PILLDROPS_API_KEY" \ -d '{"template":"code-interpreter"}' {"id":"sb_9f2","status":"running","expires_at":"..."} # 2. run model-written pandas, read stdout back $ curl -X POST https://pilldrops.com/v1/sandboxes/sb_9f2/exec \ -H "Authorization: Bearer $PILLDROPS_API_KEY" \ -d '{"cmd":"python -c \"import pandas as pd; print(pd.read_csv(...).revenue.sum())\""}' {"stdout":"48210.75\n","exit_code":0}
A code interpreter is just this cycle done fast and safely. Your model emits Python, sb.run() executes it in an isolated microVM, and r.stdout becomes the observation for the next turn.
Your LLM returns a Python snippet as its tool call — a pandas transform, a plot, a quick calculation.
sb.run() executesThe code runs inside a fresh code-interpreter sandbox — real filesystem, real interpreter, fully isolated from your host.
r.stdout backReturn stdout (or stderr on error) to the model as the observation. It reasons, corrects, and writes the next step.
from pilldrops import Sandbox import shlex sb = Sandbox.create(template="code-interpreter") while True: code = model.next_action(history) # model writes python r = sb.run(f"python -c {shlex.quote(code)}") history.append(r.stdout or r.stderr) # feed the result back if model.is_done(history): break sb.kill()
Model-written code often produces files — a matplotlib PNG, a cleaned CSV, a generated report. The image ships with matplotlib and pandas preinstalled, so pull artifacts back with the CLI or the files endpoint.
# model writes a matplotlib chart to /out/chart.png sb.run("python /data/plot.py") # saves /out/chart.png # pull the image back — CLI $ pilldrops cp sb_9f2:/out/chart.png ./chart.png # ...or over REST $ curl -H "Authorization: Bearer $PILLDROPS_API_KEY" \ "https://pilldrops.com/v1/sandboxes/sb_9f2/files?path=/out/chart.png" \ -o chart.png
The code-interpreter template ships pandas, numpy and matplotlib — no pip install round-trip before the first plot.
Push inputs with sb.upload(...), read outputs with pilldrops cp or GET /v1/sandboxes/{id}/files?path=… — images, CSVs, JSON, whatever the code wrote.
One sb.run() per model turn maps cleanly onto a single tool call. The sandbox persists across turns, so state and files carry forward — and you only pay for the seconds it runs.
Each tool call is a single run(). Stdout in, next action out — no extra plumbing.
Billed at $0.0000140/vCPU-s and $0.0000045/GB-s. Idle between turns? pause to storage-only cost, then resume.
The same write-run-read loop behind hosted code interpreters, but as an API you host and control — E2B_API_KEY works as a drop-in too.
Create a code-interpreter sandbox, run model-written pandas, read the result back — starting on $5 of free credits, no card.