Python Guest API¶
The sandbox package is available to code running inside a Python guest
runtime.
This page documents guest-side APIs. For the host-side embedding SDK that builds templates and starts sandboxes, see Python Host API.
Execution Model¶
Guest entrypoints can be regular functions or async def coroutines:
from sandbox.asyncio import hostcall
def add(a, b):
return a + b
async def lookup_user(user_id):
return await hostcall("lookup_user", {"user_id": user_id})
If a guest function returns an iterable or async iterable, each yielded item is
emitted to the host as a partial result and the final result is None:
Values crossing the host/guest boundary should be JSON-like unless you are working with raw HTTP bodies.
sandbox.asyncio¶
Import async helpers with:
await hostcall(call_type, payload) -> object¶
Calls a host-registered callback and resolves to the returned value.
from sandbox.asyncio import hostcall
async def main(user_id):
return await hostcall("lookup_user", {"user_id": user_id})
run(main)¶
Runs a coroutine or async generator on the guest poll loop from synchronous guest code.
Use this when you need to drive async work yourself from a synchronous helper or
module initialization path. When the host directly invokes an async def
function, Isola awaits it automatically and you do not need run(...).
from sandbox.asyncio import hostcall, run
async def fetch_user(user_id):
return await hostcall("lookup_user", {"user_id": user_id})
def main(user_id):
return run(fetch_user(user_id))
await subscribe(pollable) -> object¶
Low-level helper for awaiting native guest pollables. Most guest code should use
hostcall(...) or sandbox.http.fetch(...) instead of calling subscribe(...)
directly.
sandbox.http¶
Import the guest HTTP client with:
Guest HTTP is only available when the host enables outbound requests with
http=. Legacy aliases http_handler= and httpHandler= are also accepted.
See Python Host API and
Node.js Host API.
fetch(...) -> Request¶
fetch(
method,
url,
*,
params=None,
headers=None,
files=None,
body=None,
timeout=None,
proxy=None,
)
Supported request features:
params: query-string mappingheaders: string header mappingbody: rawbytesor a JSON-serializable objectfiles: multipart form fields; each value may be raw bytes, a file object, or(filename, fileobj, content_type)timeout: first-byte timeout in secondsproxy: sets thex-isola-proxyheader for host policies that honor it
If body is an object and content-type is not already set, the runtime uses
application/json.
Synchronous usage¶
from sandbox.http import fetch
def main(url):
with fetch("GET", url, params={"q": "hello"}) as resp:
return {
"status": resp.status,
"headers": resp.headers,
"body": resp.text(),
}
Response exposes:
statusheadersread(size=-1) -> bytestext() -> strjson() -> objectiter_bytes()iter_lines()iter_sse()close()
Asynchronous usage¶
from sandbox.http import fetch
async def main(url):
async with fetch("GET", url) as resp:
return await resp.atext()
AsyncResponse exposes:
statusheadersaread(size=-1) -> bytesatext() -> strajson() -> objectaiter_bytes()aiter_lines()aiter_sse()close()
Server-sent events¶
iter_sse() and aiter_sse() yield ServerSentEvent values with:
ideventdata
sandbox.importlib¶
Import remote modules over HTTP with:
http(url) returns a context manager that temporarily adds an importer to
sys.meta_path:
from sandbox.importlib import http
def main():
with http("https://example.com/modules"):
import helpers
return helpers.answer()
The URL may point at a module tree or a zip archive. This importer is also used internally for Isola's URL-based dependency loading.
sandbox.logging¶
Import structured log helpers with:
These emit guest log events back to the host sink. print(...) still writes to
stdout.
sandbox.serde¶
Import serialization helpers with:
Supported formats are "json", "yaml", and "cbor":
from sandbox.serde import dumps, loads
payload = dumps({"hello": "world"}, "json")
value = loads(payload, "json")
dumps(value, format) returns a str for JSON/YAML and bytes for CBOR.
loads(value, format) performs the reverse conversion.