Forward a port from a sandbox
Expose a sandbox port on localhost so local tools can connect to it.
sb.tunnel.forward() exposes a port (or Android abstract socket) running inside the sandbox on the local host.
Forward a single port#
Start the service inside the sandbox, then forward its port.
from cua import Sandbox, Image
async with Sandbox.ephemeral(Image.linux()) as sb:
await sb.shell.run('python3 -m http.server 8080 &')
async with sb.tunnel.forward(8080) as t:
print(t.url) # http://localhost:49823
print(t.host, t.port) # localhost, 49823The tunnel closes automatically when the async with block exits.
Forward multiple ports at once#
Pass multiple ports to get a dict[port, TunnelInfo].
async with sb.tunnel.forward(8080, 9222) as tunnels:
app_url = tunnels[8080].url
devtools_url = tunnels[9222].urlClose a tunnel manually#
If you need the tunnel outside an async with block, close it yourself.
t = await sb.tunnel.forward(8080)
print(t.url)
# ... do work ...
await t.close()Android abstract sockets#
Pass a string instead of a port number.
async with sb.tunnel.forward('chrome_devtools_remote') as t:
print(t.url) # http://localhost:<random>Abstract socket names are Linux-only (Android). On Linux and macOS sandboxes use integer port numbers.
Reference#
See Sandbox SDK interfaces for the full TunnelInfo shape.
Example: Chrome DevTools Protocol#
Start Chrome with remote debugging enabled, then read the DevTools target list through the forwarded port.
from cua import Sandbox, Image
async with Sandbox.ephemeral(Image.linux()) as sb:
await sb.shell.run('google-chrome --remote-debugging-port=9222 --headless &')
async with sb.tunnel.forward(9222) as t:
import httpx
targets = httpx.get(f'{t.url}/json').json()
print(targets)