use-computer Python SDK (daytona-use-computer)
use.computer gives you macOS sandboxes: VMs on dedicated Apple M4 Mac minis that you reserve for 24 hours or more, up to 2 VMs at a time per Mac.
pip install daytona-use-computer
export USE_COMPUTER_API_KEY=uc_live_...
Optional agent integrations are installed explicitly:
pip install "daytona-use-computer[agents]" # computer-use agents and provider SDKs
Base installs only the SDK client and httpx. The agents extra installs the agent runtime plus model-provider dependencies (Anthropic, OpenAI, Gemini, LiteLLM).
Quickstart
Flow: sign up → $100 starter credit → reserve a Mac mini (dashboard, or client.reserve(hours=24) in the SDK) → create() a macOS sandbox → drive it (mouse, keyboard, screenshot, exec, files, recording, UI tree, VNC) → delete(). The gateway configures the hourly price for each Mac model; check the live dashboard before reserving. The starter credit pays for reservations, and each reservation keeps its purchase rate.
from use_computer import Computer
client = Computer()
# 1. Reserve one M4 Mac Mini for 24 hours
reservation = client.reserve(hours=24, mac_model="m4")
# 2. Launch a macOS sandbox on the reserved Mac
with client.create(reservation_id=reservation.id) as mac:
# 3. Drive the macOS sandbox
mac.exec("open -a Safari")
mac.keyboard.type("hello from use.computer")
mac.mouse.click(500, 500)
png = mac.screenshot.take_full_screen()
print("Sandbox:", mac.sandbox_id)
# Open this sandbox's viewer from the use.computer dashboard.
Never print or share vnc_url: it contains your account API key. Open the viewer from the dashboard instead.
The optional mac_model picks the Mac: "m4" (the default; 10 vCPU and 16 GiB RAM), "m4-pro" (12 vCPU and 24 GiB RAM), or "m5-pro" (15 vCPU and 24 GiB RAM). reservation.mac_model reports it.
Each create() can set cpu, memory_gib, and disk_gib. Omitted fields select an available warm VM and start right away. Split warm VMs have 5 vCPU/8 GiB on M4, 6 vCPU/12 GiB on M4 Pro, and either 8 vCPU/12 GiB or 7 vCPU/12 GiB on M5 Pro; whole warm VMs have 10 vCPU/16 GiB, 12 vCPU/24 GiB, and 15 vCPU/24 GiB respectively. The response reports the selected slot's actual CPU and memory. Any other size boots a new VM, which can take up to 5 minutes, so create() waits up to 10 minutes when you set any of them. A Mac runs at most 2 sandboxes at a time, and their sizes must fit in the Mac. The sandbox reports cpu, memory_gib, disk_gib, and boot ("warm" or "cold"):
with client.create(reservation_id=reservation.id, cpu=8, memory_gib=12) as mac:
print(mac.cpu, mac.memory_gib, mac.boot)
If the size does not fit, create() raises SandboxResourcesError. Its code is invalid_resources, resources_exceed_mac, sandbox_limit_reached, or insufficient_capacity, and its message explains the refusal. AsyncComputer accepts the same options. Check Computer().platforms(reservation_id=...)["macos"]["capacity"] for the selected reservation's max and used counts.
The older vm_layout reservation option still works but is deprecated; the SDK sends it only when you pass it. "split" (the server default) allows two sandboxes, and "whole" allows one sandbox at a time.
When ephemeral is omitted, the server default is the reservation lifetime. Explicit ephemeral=True opts into destruction after 2 idle minutes; call sandbox.start_keepalive(interval=30) during long model-think periods. Explicit ephemeral=False disables idle destruction. Context managers still delete their sandbox on exit.
This default applies to the source release documented here. Published Python 0.0.46
still defaults to ephemeral=True; pass ephemeral=False explicitly on that
version. The next tagged release includes the omitted-field default above.
Computer actions
Coordinates use screenshot pixels. mouse.click(x, y, button="middle") selects the
middle button; click_count=3 sends one native triple-click sequence.
mouse.down() / mouse.up() hold and release the left button at the current
cursor, with optional button, x, and y. keyboard.hold("shift", 0.5) holds
keys for seconds. mouse.drag(..., path=[{"x": 10, "y": 20}, ...]) preserves all
path points. mouse.scroll(x, y, scroll_x=40, scroll_y=-80) sends both pixel
deltas (positive right/down); the direction/amount form remains available.
The async methods have the same arguments.
Provider mappings are recorded in
action_manifest.json.
Anthropic tool pixels are scaled to sandbox pixels; Gemini uses normalized
0..999 coordinates. Control and Command remain distinct. Invalid actions and
gateway errors are not reported as executed.
Agent logs separate action execution from settle+screenshot: the latter
includes a deliberate two-second settle, screenshot requests, and any recovery.
These are not model inference timings or raw screenshot latency.
exec(command, timeout=120) uses the gateway's non-login /bin/zsh -c;
exec_ax uses /bin/sh through the desktop server. The timeout is seconds
and is sent to the gateway and used as the HTTP timeout. For a 200-second
command, use timeout=300. Results retain separate stdout, stderr, and
return_code; a nonzero process exit is not an HTTP transport failure.
Application automation permissions
macOS asks for consent when a process sends Apple events to another application
through AppleScript or osascript. That consent dialog cannot be answered inside
the sandbox. The gateway approves every installed application when creating a
sandbox or restoring a snapshot. After installing another app, call
sandbox.permissions.allow_automation() to approve it before scripting it:
# Inside an async macOS sandbox session:
result = await sandbox.exec("brew install --cask firefox")
if result.return_code != 0:
raise RuntimeError(result.stderr)
approval = await sandbox.permissions.allow_automation(
bundle_ids=["org.mozilla.firefox"]
)
print(approval.success, approval.targets, approval.changed)
# Alternatively, approve all currently installed applications:
approval = await sandbox.permissions.allow_automation(installed=True)
The synchronous MacOSSandbox exposes the same method without await.
Approvals cover Apple events sent through osascript, SSH sessions, exec, and
Terminal.
allow_automation(bundle_ids=None, installed=False) sends
POST /v1/sandboxes/{sandboxID}/permissions/automation. Supply specific
bundle_ids, installed=True for all installed applications, or both in one
call. Omitted bundle IDs and the default installed=False are not sent.
The 200 response is decoded as the exported AutomationApproval dataclass:
success: bool, targets: int (applications considered), and changed: int
(approvals added or flipped from denied).
The gateway validates bundle IDs against
^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$. Malformed IDs or an empty request receive
HTTP 400 with {"error": ...}. The SDK does not validate them locally; it raises
the standard httpx.HTTPStatusError, whose response retains the status and
error body.
Runtime Snapshots
macOS snapshots let you seed a VM once, snapshot it, then create new sandboxes from that snapshot version. macOS snapshots preserve disk state, so installed apps, accounts, and seeded files are available immediately:
from use_computer import Computer
client = Computer()
# Configure the macOS desktop by hand over VNC, then snapshot it.
with client.create(type="macos") as mac:
print("Configure sandbox in the dashboard viewer:", mac.sandbox_id)
input("Press Enter once the desktop is ready to snapshot...")
snapshot = mac.snapshot("chrome-seeded-macos")
# New sandboxes boot from that saved disk state, no setup needed.
with client.create(type="macos", snapshot=snapshot.version) as seeded:
print("Seeded sandbox ready:", seeded.sandbox_id)
Use client.snapshots() to list saved snapshot versions.
Examples
| File | What it shows |
|---|---|
examples/_1_hello_macos.py |
reserve → create → exec → keyboard → screenshot |
examples/_2_recording.py |
start / stop / download a screen recording |
examples/_3_file_transfer.py |
upload bytes, download a file back |
examples/_4_keepalive.py |
heartbeat for ephemeral sessions idle > 2 min |
examples/_5_snapshots.py |
snapshot seeded macOS state |
HTTP API
Every SDK method wraps https://api.use.computer/v1/... with Authorization: Bearer uc_live_.... Swagger: api.use.computer/docs. OpenAPI spec: api.use.computer/openapi.yaml.
Gateway URLs, whether passed explicitly or via USE_COMPUTER_BASE_URL, must use HTTPS except for loopback HTTP. The SDK does not load .env files by default; load one explicitly in your application if needed. Authenticated requests, including keepalive and agent reference screenshots, do not follow redirects.
Lifecycle calls (reserve, create, and snapshot, including restores via create(snapshot=...)) send a fresh UUID v4 Idempotency-Key per call. Idempotent HTTP methods and keyed lifecycle mutations retry transient failures using the same key and body; unkeyed mutations are not retried. A new lifecycle method invocation is a new intent with a new key.
Metadata
Release files for daytona-use-computer 0.0.49
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| daytona_use_computer-0.0.49.tar.gz | 468.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| daytona_use_computer-0.0.49-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 559.8 kB
Release files / daytona_use_computer-0.0.49.tar.gz
| Download URL | daytona_use_computer-0.0.49.tar.gz |
|---|---|
| Size | 468.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4fdfe500d4b43a019ac3942391e67e4846b331c1b7665654f3f881c2516328c0
|
|
BLAKE2b-256 checksum How to use checksums |
243a777b97c432510921956abe532f60bd9a71df747fbe1fe56219dca3034852
|
| 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 2, 2026.
Transparency logRelease files / daytona_use_computer-0.0.49-py3-none-any.whl
| Download URL | daytona_use_computer-0.0.49-py3-none-any.whl |
|---|---|
| Size | 91.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9643f32de5ae37ab6e82042537ebd38159cc2fe6eb286ed3788dc079ad108422
|
|
BLAKE2b-256 checksum How to use checksums |
33aa4b72f81750e2632ba4e323cd8b45d591cc932896327d3f3679dd924a8298
|
| 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 2, 2026.
Transparency log