Skip to main content

Runtime Cloud Python SDK

One client for every Runtime Cloud product, sync and async. It needs Python 3.9 or later (the python3 that a Mac comes with). It uses only the standard library.

pip install withruntime

The client uses RUNTIME_API_KEY if it is set. If not, it uses the connection that this machine saved when you ran npx withruntime login. That takes one approval in the browser. You do not copy a key. On a server or a CI runner, set RUNTIME_API_KEY from your secret manager. To get a new key, run npx withruntime keys create. It prints the key once, after an owner, admin or developer of the account approves it in the browser. You can also create a key at https://withruntime.com/account/keys. Never put a key in source code, a URL or a command-line argument.

from withruntime import Sandbox

with Sandbox.create() as sbx:
    sbx.files.write("/workspace/invoice.py", "print(sum([125, 250, 375]))\n")
    result = sbx.exec("python3 /workspace/invoice.py")
    print(result.exit_code, result.stdout)

Sandbox.create() takes no arguments. It returns when the sandbox is running. Leaving the with block deletes the sandbox. Set keep=True to stop it instead. Its disk stays.

With no arguments, you get the free usage. No card is needed. You can run up to four sandboxes at once without credit. The current default image includes NumPy, pandas and matplotlib. See the sandbox environment. The free usage is spent first, then prepaid credit. You do not choose. funding is accepted and ignored.

AsyncRuntime is the same client for asyncio, with the same methods:

import asyncio
from withruntime import AsyncRuntime


async def main():
    async with AsyncRuntime() as runtime:
        async with await runtime.sandboxes.create() as sbx:
            print((await sbx.exec("uname -a")).stdout)


asyncio.run(main())

A sandbox has these methods and products:

  • Methods: exec, exec_stream, spawn, terminal, and forward_port (which maps a TCP port in the sandbox to a local port).
  • files: read, write, list, glob, stat, rename and remove. Upload and download directories.
  • Lifecycle: pause, wake, extend, update (its name, environment and settings), keep_alive, fork, snapshot, switch_image (moves it to a new image and keeps /workspace), and delete (removes it for good).
  • Products: interpreter, network, previews, desktop, mounts (your S3, R2 or Google Cloud Storage bucket as a folder), tailscale (a paid sandbox on your own tailnet), metrics, and mcp (servers from the MCP catalog, run in the sandbox).

A paused sandbox also wakes by itself on the next call. Sandbox.get_or_create(name) returns the sandbox with that name, or creates it.

A sandbox pauses itself after 300 seconds with nothing happening in it. It keeps its memory and processes, so an idle sandbox uses no compute. idle_pause_seconds sets the idle time from 60 to 86,400. A shorter time is raised to 60. Set it to 0 to never pause.

Each product has one plural name, as in the CLI: runtime.sandboxes, snapshots, images, volumes, jobs, domains, ports, ips and networks. The old singular names (runtime.sandbox, address, tunnel and the rest) still work for now. The guide lists them.

The client has sandboxes, images, volumes, snapshots, jobs, secrets, limits, feedback and support. It has webhooks, events, otel and audit to watch the account. It has domains, ports, ips and networks (with networks.wireguard) to connect sandboxes to your own systems (paid accounts). It has mcp, sso, billing, referrals and switching.

runtime.limits.get() (0.3.1 and later) says whether the key is read-only, and what its agent may still spend today. Every write carries an idempotency key, so a retry never runs a write twice. Errors are typed. They carry code, hint and request_id.

RuntimeAPIError and RuntimeConnectionError are the SDK's error names. They do not shadow Python's built-in errors. The older RuntimeError and ConnectionError exports are still aliases.

runtime.usage_requests("7d") reads the account's API call counts and error rates. Counts are exact decimal strings. An empty window has errorPercent: None.

runtime.usage_export(since, until, cursor=...) reads one page of settled usage over a UTC range, with its server CSV. finalThrough is the time before which no more charges will settle. Each row's final is True once its resource is deleted. After that, it cannot be charged anything more.

Behind a proxy

The client reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY, for sync and async calls. The names work in upper or lower case. If both cases are set, lower case wins.

Calls to the API and terminal WebSockets go through HTTPS_PROXY as a CONNECT tunnel. Any user:password@ in the proxy address is sent to the proxy. HTTP_PROXY is used only for http:// addresses. It is never used for the HTTPS API.

NO_PROXY lists hosts to reach directly. Split them with commas or spaces. A name covers its subdomains. A leading dot is allowed. host:port limits the rule to one port. * means every host.

A proxy address without a scheme is treated as http://. Only http:// proxies are supported. Any other scheme fails at once with invalid_proxy.

When a call cannot get through, the error names the proxy it tried. It leaves out the password. For example: No answer from Runtime at https://api.withruntime.com through the proxy http://proxy.internal:3128 (HTTPS_PROXY).

Code written for E2B

withruntime.e2b translates supported E2B Python sandbox calls. Change the import and set RUNTIME_API_KEY:

from withruntime.e2b import Sandbox, AsyncSandbox  # was: from e2b import ...
from withruntime.e2b.code_interpreter import Sandbox  # was: from e2b_code_interpreter import Sandbox

Sandboxes get E2B's defaults: 2 vCPU and 512 MiB. There is no time limit unless you pass timeout. A sandbox runs while it works, and pauses itself when it is idle. Timeouts are in seconds, as in E2B's Python SDK. runtime_create={...} passes Runtime's own create fields, for example {"idle_pause_seconds": 0}.

A call that Runtime does not handle the way E2B does raises NotSupportedException before anything happens. The error names what to use instead. Importing withruntime alone does not load it. The sync Sandbox is generated from the async one by scripts/generate_e2b_sync.py.

Code written for Daytona or Vercel Sandbox

withruntime.daytona and withruntime.vercel do the same for Daytona's Python SDK and Vercel Sandbox's. Change the import:

from withruntime.daytona import Daytona, AsyncDaytona  # was: from daytona import ...
from withruntime.vercel import sandbox  # was: from vercel import sandbox
from withruntime.vercel.sandbox import sync as sandbox  # was: from vercel.sandbox import sync as sandbox

Sandboxes get the rival's defaults. For Daytona, that is 1 vCPU, 1 GiB and a 3 GiB disk. It pauses after 15 idle minutes. For Vercel, that is 2 vCPUs with 2048 MiB each. Vercel sandboxes are persistent, with no time limit unless you pass one. runtime_create={...} passes Runtime's own create fields.

A Daytona or Vercel key is never sent anywhere. A call that Runtime does not handle the same way raises NotSupportedError before anything happens. The error names what to use instead. The sync modules are generated from the async ones by scripts/generate_dropin_sync.py. DAYTONA.md and VERCEL.md in the JavaScript package list every mapping and gap.

Code written for Blaxel

withruntime.blaxel translates supported Blaxel Python sandbox calls (blaxel 0.4.11) on Runtime. Change the import and set RUNTIME_API_KEY. Or run npx withruntime login once:

from withruntime.blaxel import SandboxInstance  # was: from blaxel.core import SandboxInstance
from withruntime.blaxel import SyncSandboxInstance  # was: from blaxel.core import SyncSandboxInstance

withruntime.blaxel.core holds the same names. So replacing blaxel. with withruntime.blaxel. also works. A Runtime key in BL_API_KEY is used. A Blaxel key is never sent anywhere.

How it maps:

  • Sandboxes. create, create_if_not_exists (one sandbox when two calls race), get, get_by_external_id, list, delete, fork, snapshots and the update_* calls work. memory is kept, with one vCPU for every 2048 MB. Blaxel's general templates run on Runtime's image: blaxel/base-image, py-app, ts-app, node, jupyter-server and docker-in-sandbox. Any other image ns/name:tag starts from the ready Runtime image ns-name:tag. Every / becomes -. The tag is latest when none is given. So the code keeps Blaxel's image string. A missing image raises NotSupportedError with the build command. For example: npx withruntime images build --dockerfile Dockerfile --name my-company-agent-image -t my-company-agent-image:latest. Volumes mount Runtime volumes of the same name. Without credit, a sandbox has at most 4096 MB of memory (2 vCPUs).
  • Standby. A sandbox pauses after a minute with no call. Blaxel's standby time is about 15 seconds. A paused sandbox keeps its memory and processes. It wakes on the next command, file call or preview visit. archive pauses it and keeps its memory too. A sandbox has no time limit, so a long command is never paused by a clock. keep_alive raises the idle pause to the process's time limit. For a process with no time limit, it turns the idle pause off. The first call from any client that finds no keep_alive process running brings back the old idle pause.
  • How long it is kept. A paused sandbox with no ttl or lifecycle is kept 365 days. Blaxel keeps it until you delete it. A limit is rounded up to whole days of pause. A limit of an hour or less, counted from creation, also ends the sandbox at that time. Without credit, a paused sandbox is kept seven days. That is the most Blaxel's first tier keeps.
  • Envs reach every process, from any client. They are kept on the sandbox. A process's own env wins.
  • Paths. /blaxel is Blaxel's working directory and HOME. On Runtime it is /workspace. Relative paths and ~ start there.
  • Processes. You can find a process by name from any client, as long as Runtime still has its record. Runtime keeps the running processes and the last 16 that ended.
  • Previews are Runtime previews of each port. A private preview's tokens.create(expires_at) gives a token. The token works as Blaxel's X-Blaxel-Preview-Token header or bl_preview_token address parameter. fetch(port) uses a private preview for you.
  • Code interpreter. CodeInterpreter.run_code and create_code_context run on Runtime's interpreter. They return Blaxel's result classes.
  • Errors. Errors keep Blaxel's classes: SandboxAPIError, ResponseError and SnapshotAPIError. Each one also carries Runtime's code, hint and request_id.
  • Runtime fields. runtime_create={...} passes Runtime's own create fields, for example {"idle_pause_seconds": 0}. sandbox.withruntime is the Runtime sandbox underneath.

Differences you can hit:

  • Commands run as root, as on Blaxel, with the sandbox's PATH and HOME (/workspace). File calls act as the sandbox user. They fall back to sudo where only root may act. So they reach files that a root process made, including private ones. A file they write belongs to the sandbox user.
  • A key sees the sandboxes it made. Another key's calls get 404. The exception is when an owner or admin makes the key account-wide, as a Blaxel workspace key is (teams).
  • Public previews need a paid sandbox.
  • A process's pid is Runtime's process id. It is not an operating-system number.
  • sandbox.sessions makes a Runtime sandbox session. SandboxInstance.from_session drives the sandbox with its token. That gives commands, files and previews of that one sandbox. A session lasts a day at most. Access-Control-Allow-Origin in response_headers names the page that may use it.

These raise NotSupportedError before anything happens. The error names what to use instead: regions outside the US, read-only and ephemeral volumes, drives, extra_args other than iptables, egress and subnet settings, preview headers, custom domains and preview expiry, restoring a snapshot in place (fork from it instead), codegen, system, schedules, and Blaxel's agents, models, tools, jobs and applications. The sync module is generated from the async one by scripts/generate_dropin_sync.py.

Code written for Modal Sandboxes

withruntime.modal runs code written for Modal's Sandboxes (modal 1.6.2), sync and .aio. Change the import and set RUNTIME_API_KEY:

from withruntime import modal  # was: import modal

Modal's own sandbox examples run unchanged if they use none of the features refused below. A Modal token is never needed or sent. Commands run as root, as in a Modal container. A timeout ends the sandbox. An idle_timeout pauses it and keeps its memory. The next call wakes it.

Images build from Modal's recipes. publish(name) makes a Runtime image name that Image.from_name finds. Memory snapshots (_experimental_enable_snapshot) keep the running entrypoint.

These raise CompatibilityError before anything is created. The error names what to use instead: GPUs; Modal Functions and Dicts; named secrets; volumes made on first use; sidecars; connect tokens; and directory snapshots. COMPATIBILITY.md lists every mapping.

Agent frameworks

withruntime.openai_agents is a sandbox client for the OpenAI Agents SDK's SandboxAgent. Install it with pip install "withruntime[openai-agents]". withruntime.deepagents is a Deep Agents sandbox backend. withruntime.tools gives LangChain, CrewAI, LlamaIndex, Pydantic AI, Google ADK and any framework that takes typed functions four sandbox tools. See https://withruntime.com/docs/frameworks.

How Runtime compares

For typical agent work, Runtime costs 42% to 88% less than fourteen other sandbox providers at their published rates. These pages show the arithmetic. Each one lists the rates it used and the date they were read:

Reliability and support

Docs: https://withruntime.com/docs/python.

The package was called withruntime-cloud, imported as runtime_cloud, until 0.3.0. That name stopped at 0.5.1. It gets no new releases. Use withruntime.

Metadata

Release files for withruntime 0.44.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for withruntime 0.44.0
File Size Uploaded Provenance Actions
withruntime-0.44.0.tar.gz 896.7 kB With provenance Details for withruntime-0.44.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for withruntime 0.44.0
File Interpreter ABI Platform Actions
withruntime-0.44.0-py3-none-any.whl Python 3 none any Details for withruntime-0.44.0-py3-none-any.whl

Total release size: 1.6 MB

Release files / withruntime-0.44.0.tar.gz

Download URL withruntime-0.44.0.tar.gz
Size 896.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d4580de64bb51a01e9b133e0958e14c42769b216c10e41cf4563e75f5164fc1d
BLAKE2b-256 checksum
How to use checksums
cfa2fdc37044241185bfcf0a098920dd60b1c8f7f9e4590bdf5e2731fef789ad
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 28, 2026.

Transparency log

Release files / withruntime-0.44.0-py3-none-any.whl

Download URL withruntime-0.44.0-py3-none-any.whl
Size 726.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd47b2b789a51093245520c5acb0099b6de66a39059219efb19969dd88a123be
BLAKE2b-256 checksum
How to use checksums
7c709b309eaf6717dc188cf0a1683fd594af66e3ad015f4291ca21633db5e265
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 28, 2026.

Transparency log

Security for withruntime 0.44.0

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for withruntime-0.44.0.tar.gz

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 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.44.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page