Python SDK

The official Python SDK for MIOSA. Every resource has a sync and an async class: pick Miosa or AsyncMiosa at construction. Requires Python 3.9 or newer.

Install

pip install miosa
from miosa import Miosa, AsyncMiosa, Sandbox, Computer, Forge

Extras: miosa[events] (websockets), miosa[http2], miosa[dev]. The agent runtime is a separate module: from miosa.agent import Agent.

Authentication

from miosa import Miosa

client = Miosa(api_key="msk_u_...")           # sync
async_client = AsyncMiosa(api_key="msk_u_...") # async

api_key and access_token are mutually exclusive: passing both raises ValueError. Key resolution order is access_token, api_key, MIOSA_ACCESS_TOKEN, MIOSA_API_KEY. Other options: tenant (MIOSA_TENANT), base_url (MIOSA_BASE_URL, default https://api.miosa.ai/api/v1), timeout (default 60s), max_retries (default 3), unbranded.

Both clients are context managers. client.with_tenant(tenant) returns a client acting in another organization. Use client.get_balance(), client.get_usage() and client.get_transactions() for account reads.

Sandboxes

sbx = client.sandboxes.create(name="my-box", size="small")
sbx.wait_until_ready()
MethodWhat it does
client.sandboxes.create(template_id=None, *, name=None, size=None, ...)Create a sandbox
client.sandboxes.list(*, state=None, tags=None, ...)List
client.sandboxes.get(sandbox_id)Get one
client.sandboxes.get_by_name(name)Get by name
client.sandboxes.get_or_create(name, *, resume=True, ...)Reuse or create
client.sandboxes.delete(sandbox_id)Delete

On the handle, sandbox.stop() stops it (the disk is kept, processes are not) and sandbox.resume() brings it back; sandbox.destroy() deletes it (delete is an alias). Sizes are xs, small, medium, large, xl.

Exec and files

r = sbx.exec.run("node -v")      # ExecResult(stdout, stderr, exit_code, duration_ms)
sbx.exec("npm test")             # the exec runner is callable
sbx.run("npm test")              # delegates to exec.run
for ev in sbx.exec.stream("npm run dev"):
    print(ev)
sbx.commands.run("ls -la")       # richer: background processes, pid

Computer exec is separate:

computer.bash("ls -la")
computer.python("print(2 + 2)")

Files differ between sandboxes and computers. Sandbox files have no mkdir or rm:

sbx.files.write("/workspace/app.py", code)
sbx.files.read_text("/workspace/app.py")
sbx.files.list("/workspace")
# directory create/remove: use exec
sbx.exec.run("mkdir -p /workspace/out")

computer.files.write_file("/home/user/notes.txt", "hi")
computer.files.mkdir("/home/user/data", recursive=True)
computer.files.delete("/home/user/old")

Sandbox file methods: list, read, read_text, write, write_many, upload, download, stat, tree, watch. Flat shims on the handle: write_file, read_file, list_files, stat_file, upload, download.

Snapshots

sbx.snapshots.create(comment="before deps")
sbx.snapshots.list()
sbx.snapshots.restore(snapshot_id)
sbx.create_snapshot()            # convenience
SurfaceMethods
sbx.snapshotscreate, list, restore, delete
client.snapshotslist, get
client.snapshot_historylist, groups, get, delete, bulk_delete, tree, file, fork
client.named_snapshotslist, create, get, delete, deploy

Computers

computer = client.computers.create(name="dev-box", size="small")
computer.start()
computer.wait_until_ready()
MethodWhat it does
client.computers.create(name, *, template_type="miosa-desktop", size="small", ...)Create
client.computers.list(*, workspace_id=None)List
client.computers.get(computer_id)Get one
client.computers.update(computer_id, ...)Update
client.computers.delete(computer_id)Delete

Desktop control: screenshot() (bytes), screenshot_base64(), click, right_click, double_click, type, key, hotkey, scroll, drag, move_cursor, launch, windows, accessibility_tree, set_clipboard, set_wallpaper.

Agents

There is no client.agents. Agent surfaces:

computer.agent.run("open the editor")     # computer control session
client.runs.run(instruction="...", target_kind="sandbox", target_id=sbx.id)
sbx.run_agent("fix tests")                # convenience, runner "claude-code"
sbx.prompt("fix tests")                   # convenience, provider "claude"
SurfacePurpose
computer.agentControl sessions: run, list, get, cancel, pause, resume, task
client.runsrun, list, get, cancel, outputs, files, messages, diagnostics
client.agent_runsrun, list, get, cancel, artifacts, events, wait_for_completion
miosa.agentADK: Agent, miosa_tools, provider factories

miosa.agent.Agent needs tools= or miosa_api_key=; it raises ValueError otherwise.

Errors

from miosa import Miosa, RateLimitError

try:
    client.sandboxes.get("missing")
except RateLimitError as err:
    print(err.retry_after)

All errors extend MiosaError, which carries status_code, code, body, details, request_id, retryable and retry_after_ms. Branch on err.code (a string), not err.status_code. Status-mapped subclasses (AuthenticationError, PermissionError, NotFoundError, ValidationError, RateLimitError, InsufficientCreditsError, ServerError, TimeoutError, ConnectionError) plus around 55 typed errors are exported from the package root.

Was this page helpful?