Data pipelines
Run untrusted data transformations in disposable sandboxes — perfect for ETL, scraping, and one-off batch jobs.
Use disposable sandboxes to isolate ETL steps, scrapers, and batch transforms. Put files through sandbox.filesystem and execute code with exec or run_code.
from pandastack import Sandbox
sandbox = Sandbox.create(
template="code-interpreter",
ttl_seconds=3600,
metadata={"pipeline": "daily-import"},
)
sandbox.filesystem.upload("./input.csv", "/workspace/input.csv")
result = sandbox.exec(
"python -c \"import pandas as pd; df=pd.read_csv('/workspace/input.csv'); df.to_json('/workspace/output.json')\"",
timeout_seconds=300,
)
if result.exit_code != 0:
print("\n".join(sandbox.logs(stream="both", follow=False)))
raise RuntimeError(result.stderr)
sandbox.filesystem.download("/workspace/output.json", "./output.json")
sandbox.kill()import { Sandbox } from "@pandastack/sdk";
const sandbox = await Sandbox.create({
template: "code-interpreter",
ttlSeconds: 3600,
metadata: { pipeline: "daily-import" },
});
await sandbox.filesystem.upload("./input.csv", "/workspace/input.csv");
const result = await sandbox.exec(
"python -c \"import pandas as pd; df=pd.read_csv('/workspace/input.csv'); df.to_json('/workspace/output.json')\"",
{ timeoutSeconds: 300 },
);
if (result.exitCode !== 0) {
for await (const line of sandbox.logs({ stream: "both" })) console.log(line);
throw new Error(result.stderr);
}
await sandbox.filesystem.download("/workspace/output.json", "./output.json");
await sandbox.kill();pandastack sandbox create --template code-interpreter --ttl 3600 --metadata pipeline=daily-import
pandastack fs upload <id> --local ./input.csv --remote /workspace/input.csv
pandastack fs write <id> --path /workspace/transform.py \
--content 'import pandas as pd; df=pd.read_csv("/workspace/input.csv"); df.to_json("/workspace/output.json")'
pandastack sandbox exec <id> --timeout 300 -- python /workspace/transform.py
pandastack fs download <id> --remote /workspace/output.json --local ./output.json
pandastack sandbox logs <id> --stream both # on failure, inspect both streams
pandastack sandbox delete <id># Create the sandbox
curl -X POST https://api.pandastack.ai/v1/sandboxes \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template": "code-interpreter", "ttl_seconds": 3600, "metadata": {"pipeline": "daily-import"}}'
# Upload the input file and the transform script
curl -X PUT "https://api.pandastack.ai/v1/sandboxes/<id>/fs?path=/workspace/input.csv" \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
--data-binary @./input.csv
printf 'import pandas as pd\ndf = pd.read_csv("/workspace/input.csv")\ndf.to_json("/workspace/output.json")\n' |
curl -X PUT "https://api.pandastack.ai/v1/sandboxes/<id>/fs?path=/workspace/transform.py" \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
--data-binary @-
# Run it (check exit_code in the response)
curl -X POST https://api.pandastack.ai/v1/sandboxes/<id>/exec \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"cmd": "python /workspace/transform.py", "timeout_seconds": 300}'
# Download the result, then clean up
curl "https://api.pandastack.ai/v1/sandboxes/<id>/fs?path=/workspace/output.json" \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
-o ./output.json
curl -X DELETE https://api.pandastack.ai/v1/sandboxes/<id> \
-H "Authorization: Bearer $PANDASTACK_API_KEY"Python batch job
Shown in the Python tab above.
TypeScript batch job
Shown in the TypeScript tab above.
CLI debugging
The step-by-step CLI equivalent is in the CLI tab above — handy for poking at a pipeline sandbox interactively.
CI runners
Run untrusted PR CI inside ephemeral Firecracker microVMs — no sandbox-escape risk.
Execute Python in an isolated microVM via one API call
How to execute Python in an isolated microVM with one API call — create a Firecracker sandbox, run code, and read stdout from the Python or TypeScript SDK or raw curl.