Get started
upstream gives every AI agent its own Firecracker microVM: a real Linux machine with its own kernel, network and disk. You create sandboxes, run commands and move files through one API, and fork a running sandbox into as many copies as you need.
Install#
The Python SDK is upstm-py. It supports Python 3.10 and later, and imports as upstream.
$ pip install upstm-pyAuthenticate#
API keys start with ak_. Keep yours in an environment variable and pass it to the client:
$ export UPSTREAM_API_KEY=ak_…import os
from upstream import Upstream
client = Upstream(api_key=os.environ["UPSTREAM_API_KEY"])The key travels as a bearer token, so calling the API directly works the same way.
Run your first sandbox#
with client.sandbox(template="python") as sb:
result = sb.exec(["python3", "-c", "import platform; print(platform.system())"])
print(result.stdout) # Linux
print(result.exit_code) # 0client.sandbox() starts a microVM from the python template and returns once it is ready. Leaving the with block destroys it.
Read and write files#
with client.sandbox(template="python") as sb:
sb.write_file("/workspace/main.py", "print(sum(range(10)))")
print(sb.exec(["python3", "/workspace/main.py"]).stdout) # 45
print(sb.list_files("/workspace"))Commands run in /workspace by default. For large files, use pre-signed URLs instead of sending contents through the API.
Fork it#
A fork is a copy of a running sandbox. It resumes with its parent's memory, files and processes, and shares the parent's pages until it writes to them. Prepare a machine once, then branch from it as often as you like.
with client.sandbox(template="python") as base:
base.write_file("/workspace/state.txt", "prepared")
child = base.fork()
child.write_file("/workspace/state.txt", "changed in the fork")
print(base.read_file_text("/workspace/state.txt")) # prepared
print(child.read_file_text("/workspace/state.txt")) # changed in the fork
child.destroy()The forking guide covers parallel attempts, debugging from a failure, snapshots and pausing.