Quick Start¶
Get Tako VM running and execute your first code.
Install and Start¶
pip install "tako-vm[server]"
tako-vm setup # pull the executor Docker image
tako-vm server # starts on http://localhost:8000
tako-vm server auto-starts a PostgreSQL container on port 55432 for job persistence. Use --port to change the server port:
gVisor on Linux
Tako VM defaults to permissive mode, which falls back to runc if gVisor is not installed. For production, set security_mode: strict to require gVisor. See Security for installation instructions.
Security: Environment Variables
Do not pass secrets (API keys, tokens, passwords) as job type environment variables. User code can read them via /proc/self/environ. Pass sensitive data through input_data instead, which is scoped to a single job. See Security Mitigations for details.
Execute Code¶
Using curl¶
curl -X POST http://localhost:8000/execute \
-H "Content-Type: application/json" \
-d '{"code": "print(1 + 1)"}'
Using Python¶
import requests
code = """
import json
# Read input from /input/data.json
with open("/input/data.json") as f:
data = json.load(f)
# Process
result = {
"sum": data["x"] + data["y"],
"product": data["x"] * data["y"]
}
# Write output to /output/result.json
with open("/output/result.json", "w") as f:
json.dump(result, f)
print("Done!")
"""
response = requests.post(
"http://localhost:8000/execute",
json={
"code": code,
"input_data": {"x": 10, "y": 20},
"requirements": ["numpy"] # Optional: ad-hoc dependencies
}
)
result = response.json()
print(f"Success: {result['success']}")
print(f"Output: {result['output']}")
print(f"Stdout: {result['stdout']}")
Sync vs Async Execution¶
| Endpoint | Behavior | Best For |
|---|---|---|
POST /execute |
Blocks until complete, returns result directly | Quick jobs (<30s), simple scripts |
POST /execute/async |
Returns job_id immediately, poll for result |
Long jobs, queued workloads, production |
Sync (Blocking)¶
# Blocks until done - simple but ties up the connection
response = requests.post("http://localhost:8000/execute", json={
"code": "print('hello')"
})
print(response.json()["stdout"]) # "hello"
Async (Non-blocking)¶
# Returns immediately with job_id
response = requests.post("http://localhost:8000/execute/async", json={
"code": "import time; time.sleep(10); print('done')"
})
job_id = response.json()["job_id"]
# Option 1: Poll for status
status = requests.get(f"http://localhost:8000/jobs/{job_id}").json()
print(status["status"]) # "running" or "succeeded"
# Option 2: Block until complete (with timeout)
result = requests.get(
f"http://localhost:8000/jobs/{job_id}/result?wait=true&timeout=30"
).json()
print(result["stdout"]) # "done"
When to use async
Use async (/execute/async) when:
- Jobs may take more than a few seconds
- You need idempotency keys for safe retries
- You want to submit multiple jobs and collect results later
- You're building a production system with job queuing
Understanding the Execution Model¶
Your code runs in an isolated Docker container with three mounted directories:
| Path | Permission | Purpose |
|---|---|---|
/input/data.json |
Read-only | Input data (JSON) |
/output/ |
Read-write | Output files |
/code/main.py |
Read-only | Your code |
Container Filesystem
├── /input/
│ └── data.json ← Your input_data as JSON
├── /output/
│ └── result.json ← Write your output here
├── /code/
│ └── main.py ← Your code
└── /tmp/ ← Temporary files (writable)
Output Files (Artifacts)
All output files must be written to /output/ - this is the only writable directory besides /tmp/.
/output/result.jsonis special: it's automatically parsed and returned in theoutputfield- Any other files in
/output/(e.g.,report.txt,data.csv) are saved as artifacts - Download artifacts via
GET /jobs/{job_id}/artifacts/{filename} - Files written elsewhere are lost when the container is destroyed
Response Format¶
{
"success": true,
"output": {"sum": 30, "product": 200},
"stdout": "Done!\n",
"stderr": "",
"exit_code": 0,
"execution_time": 0.35,
"job_type": "default"
}
| Field | Description |
|---|---|
success |
Whether execution completed without errors |
output |
Contents of /output/result.json (parsed) |
stdout |
Standard output from your code |
stderr |
Standard error from your code |
exit_code |
Process exit code (0 = success) |
execution_time |
Wall clock time in seconds |
job_type |
Environment used |
Next Steps¶
- Basic Execution - Input/output patterns, multiple artifacts
- Configuration - Customize Tako VM settings
- Environments - Use different packages
- Async Jobs - Long-running tasks with artifact downloads