microvms
Run coding agents and their tools in sandboxed AWS Lambda MicroVMs. Give each
task its own Linux workspace, execute commands, collect files, and terminate
the VM from Python. AgentVm runs Claude Code or Codex through Amazon
Bedrock; Sandbox supports your own agent or command runner.
Install
python3 -m venv .venv
. .venv/bin/activate
python -m pip install microvms
Requires CPython 3.11+. On Windows, activate with
.venv\Scripts\Activate.ps1 in PowerShell. Wheels ship for Linux x64/ARM64
(glibc), macOS Intel/Apple Silicon, and Windows x64. Type declarations are included.
Run your first command
This example starts a VM from an image, runs a command, and cleans up. Set up AWS and build the image first. Each launch creates resources that AWS bills to your account.
You need Lambda MicroVMs access, your normal AWS credential configuration,
and an execution role. Follow AWS setup
to set AWS_REGION and MICROVM_EXECUTION_ROLE_ARN. Then use the
CLI
to prepare an image containing agentd:
microvm build --name agent-tools --json
export MICROVM_IMAGE='paste data.imageIdentifier from the result'
Use the image ARN, in the same account and region as your credentials.
The SDK can also look up an image by name in that region. This example uses
the ARN returned by the build.
The CLI provisions agentd and uploads the build artifact for you. Shell
examples use Bash or Zsh; in PowerShell, set variables with $env:NAME='value'.
Save as hello.py:
import os
import sys
from microvms import Region, Sandbox
image = os.environ["MICROVM_IMAGE"]
role = os.environ["MICROVM_EXECUTION_ROLE_ARN"]
vm = Sandbox(Region.parse(os.environ.get("AWS_REGION", "us-east-1")))
try:
session = vm.run(image_identifier=image, execution_role_arn=role)
result = session.run_sync(["echo", "hello from a sandbox"])
print(result.stdout, end="")
print(result.stderr, end="", file=sys.stderr)
if not result.ok:
raise RuntimeError(f"Command exited with {result.exit_code}")
finally:
cleanup = vm.terminate()
if cleanup.failures or cleanup.undeleted:
print("Cleanup needs attention:", cleanup.to_dict(), file=sys.stderr)
python hello.py
Expected output: hello from a sandbox. The VM is terminated after the
command; the image stays available for reuse. terminate() returns once
termination is accepted by default. Pass wait_for_terminated=True to
wait for the final state. Inspect failures and undeleted because cleanup
reports failures in its result.
Run a coding agent
First prepare a Claude Code image using the same AWS setup plus Bedrock permissions. This builds or reuses the agent image and starts a temporary VM. Capture only its image ARN, then terminate that temporary VM:
MICROVM_AGENT_IMAGE="$(microvm agent-up --vm-name sdk-image --agent claude-code --json |
python -c 'import json, sys; print(json.load(sys.stdin)["data"]["imageIdentifier"])')"
export MICROVM_AGENT_IMAGE
microvm terminate sdk-image --wait
Save as agent.py. The agent writes a file inside its own VM; the SDK
downloads that file before cleanup:
import os
import sys
from microvms import AgentVm, Region
image = os.environ["MICROVM_AGENT_IMAGE"]
role = os.environ["MICROVM_EXECUTION_ROLE_ARN"]
vm = AgentVm(Region.parse(os.environ.get("AWS_REGION", "us-east-1")))
try:
session = vm.launch(image_identifier=image, execution_role_arn=role)
vm.install_access()
result = vm.prompt_sync(
"claude-code",
"Create /workspace/hello.py that prints hello from a sandbox. Run it.",
)
print(result.stdout, end="")
print(result.stderr, end="", file=sys.stderr)
if not result.ok:
raise RuntimeError(f"Agent exited with {result.exit_code}")
with open("hello-from-agent.py", "wb") as artifact:
artifact.write(session.download_file("/workspace/hello.py"))
finally:
cleanup = vm.terminate()
if cleanup.failures or cleanup.undeleted:
print("Cleanup needs attention:", cleanup.to_dict(), file=sys.stderr)
python agent.py
For Codex, prepare the image with --agent codex, import AgentSpec, create
AgentVm(region, [AgentSpec.codex()]), and prompt "codex".
Agent images must contain the agent you select. Agents run as UID/GID 1000
in /workspace; install_access() installs a short-lived Bedrock token
after launch. AgentVm enables internet egress for model calls.
Next steps
For a Sandbox named vm and its session:
| Need | API |
|---|---|
| Start a task and poll or stream later | session.run(argv) → ExecHandle |
| Read stdout and stderr as separate bytes | session.spawn(argv) → ExecProcess |
| Wait for and release saved output | handle.wait_and_ack(timeout=60) |
| Keep the VM awake while an exec runs | with session.keep_awake(while_busy=True): ... |
| Upload input or download results | session.upload_file(path, bytes), session.download_file(path) |
| Sync a directory in, bring files back | session.sync_dir(local_dir), session.download_dir(path, local_dir, ["**"]) |
| Move a tar archive as bytes | session.upload_tar(path, tar_bytes), session.download_tar(path) |
| Freeze and restore a workspace | vm.suspend(), vm.resume() |
Each method that calls AWS or the VM blocks, and has an awaitable twin with the
same arguments and an _async suffix for asyncio code (see below). run_sync
starts a command, waits, and acknowledges its saved output. A nonzero exit is a result, so check result.ok or
result.exit_code. Use shell=True when passing a shell script string.
Library exceptions expose code, kind, wire_kind, and retryable.
Omitting egress does not block outbound traffic. For no egress, use
egress_network_connectors=[vpc_connector_arn] with a VPC without an internet
gateway, NAT gateway, or other internet route. deny_egress sets advisory proxy variables that
workloads can bypass. Keep the guest execution role limited to the task's needs.
Use it from asyncio
Every method that calls AWS or the VM has an awaitable twin named with an
_async suffix, and the constructors have create_async. A twin takes the same
arguments and returns the same result, and its work runs on the library's own
runtime, so the event loop keeps running and many calls overlap:
import asyncio
import os
from microvms import Region, Sandbox, Session
async def main() -> None:
region = Region.parse(os.environ.get("AWS_REGION", "us-east-1"))
async with await Sandbox.create_async(region) as vm:
session = await vm.run_async(
image_identifier=os.environ["MICROVM_IMAGE"],
execution_role_arn=os.environ["MICROVM_EXECUTION_ROLE_ARN"],
)
proc = await session.spawn_async(["sh", "-c", "echo out; echo err >&2"])
async for chunk in proc.stdout:
print(chunk.decode(), end="")
# An attached session has a transport of its own, so its calls overlap.
worker = await Session.attach_async(
region, vm.microvm_id, vm.endpoint, session.agent_token
)
results = await asyncio.gather(
*(worker.run_sync_async(["echo", str(n)]) for n in range(3))
)
print([result.stdout.strip() for result in results])
asyncio.run(main())
async with terminates the VM on the way out, as with does. Canceling a
read, wait, transfer or command start stops it. Canceling run_async,
build_image_async, ensure_image_async, suspend_async, resume_async or
terminate_async lets the call finish, so a VM a canceled launch started is
still the sandbox's to terminate. Calls through the sandbox's own session take
turns on the sandbox, as the blocking methods do, so a lifecycle call never
interleaves with them; Session.attach_async gives a session whose calls run at
once. A property such as vm.lifecycle waits for a transition
in flight, so read it before or after awaiting one.
SDK tutorial · API reference · Source · Apache-2.0
Metadata
Release files for microvms 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| microvms-1.1.1.tar.gz | 1.2 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| microvms-1.1.1-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details |
| microvms-1.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| microvms-1.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| microvms-1.1.1-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
| microvms-1.1.1-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 25.0 MB
Release files / microvms-1.1.1.tar.gz
| Download URL | microvms-1.1.1.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
462730570074c4bcded599e191a7cf0f8e4e9deb7fd507bee09c3b40b70f664d
|
|
BLAKE2b-256 checksum How to use checksums |
7e5555a1d080dcfa9cf8ee008b586e9af56b5170c503da764ba39b5b24127a77
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / microvms-1.1.1-cp311-abi3-win_amd64.whl
| Download URL | microvms-1.1.1-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
732215f394f67e34e8f7c3b807830622d5a7fbe734b1e3cdb5ce26c53f296e9c
|
|
BLAKE2b-256 checksum How to use checksums |
a39d4f5a2c331532f6bf9a2ab1bc31abd87782d885fafa669856c0ef5e63aab2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / microvms-1.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | microvms-1.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 5.0 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
7a8ee44b8424f3aec77bd63f33e4eb72fcfa10102404f3bda007df9ec564fd92
|
|
BLAKE2b-256 checksum How to use checksums |
02b6c18476f160d2122973a11c653e4bfaef5a3235969439fb173ce4e4a2131b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / microvms-1.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | microvms-1.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
9c9beab8824c037110ec947fb56933900ca26e8e7685b187a1e07b01554fc3c0
|
|
BLAKE2b-256 checksum How to use checksums |
b271f1f4e8d05d4cf07e8455c945777291ff0ee68fad1e00e8885c4cfa2bfbac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / microvms-1.1.1-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | microvms-1.1.1-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
72800ce77046d6a8f037775e5736ab7dbe5a72e090243c156a6b4bcca76b1b6b
|
|
BLAKE2b-256 checksum How to use checksums |
7697b1826e844cecf5312111d585e32dac31e7453edd14b37c8e3e3a9b7dd0cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / microvms-1.1.1-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | microvms-1.1.1-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
e689821f5403840bf6d6d0f1aff687d395ce402c66d65f018550971aa189891f
|
|
BLAKE2b-256 checksum How to use checksums |
dee782228093040f7b244e67816ff31ea784b05bc2f7b7116f1b3cd7b780e3db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log