Documentation Index
Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
Use case
Every sandbox exposes a set of path-based URLs under api.declaw.ai
for interacting with its filesystem, ports, and MCP endpoint. This
example exercises each URL helper and round-trips a 50 MiB payload
through the upload/download endpoints to verify streaming works
end-to-end.
All URLs are path-based under api.declaw.ai. Subdomain-style
URLs (<id>.api.declaw.ai) are not supported.
What you’ll learn
- Using
envd_api_url to get the base namespace URL for a sandbox
- Building download and upload URLs with
download_url(path) /
upload_url(path)
- Using
get_host(port) for port-based reverse-proxy URLs
- Using
get_mcp_url() for the MCP convenience endpoint
- Round-tripping a large payload through
upload_url + download_url
with SHA-256 verification
Prerequisites
export DECLAW_API_KEY="your-api-key"
export DECLAW_DOMAIN="your-declaw-instance.example.com:8080"
Code walkthrough
Create a sandbox and print all five URL helpers:
from declaw import Sandbox
sbx = Sandbox.create(template="base", timeout=600)
print(f"envd_api_url: {sbx.envd_api_url}")
print(f"download_url: {sbx.download_url('/tmp/hello.bin')}")
print(f"upload_url: {sbx.upload_url('/tmp/hello.bin')}")
print(f"get_host(3000): {sbx.get_host(3000)}")
print(f"get_mcp_url(): {sbx.get_mcp_url()}")
Round-trip a 50 MiB payload through the raw file streaming endpoints:
import hashlib, os, random
import httpx
api_key = os.environ["DECLAW_API_KEY"]
headers = {"X-API-Key": api_key}
client = httpx.Client(http2=True, timeout=120)
random.seed(0xC0FFEE)
payload = bytes(random.randbytes(50 * 1024 * 1024))
want_hash = hashlib.sha256(payload).hexdigest()
# Upload
resp = client.put(
sbx.upload_url("/tmp/roundtrip.bin"),
content=payload,
headers={**headers, "Content-Type": "application/octet-stream"},
)
assert resp.status_code == 200
# Download and verify
resp = client.get(
sbx.download_url("/tmp/roundtrip.bin"),
headers=headers,
)
got = resp.content
got_hash = hashlib.sha256(got).hexdigest()
assert got_hash == want_hash, "hash mismatch"
print(f"Round-trip PASS: {len(got)} bytes, sha256 matches.")
Port proxy — start a server inside the sandbox and access it through
get_host():
# Port proxy — start a server and access it through get_host()
sbx.commands.run(
"nohup perl -e '"
"use IO::Socket::INET;"
"my $s=IO::Socket::INET->new(Listen=>10,LocalPort=>3000,ReuseAddr=>1) or die;"
"while(1){"
" my $c=$s->accept or next; <$c>;"
" 1 while defined($_=<$c>) && /\\S/;"
' my $b="port-proxy-ok";'
' print $c "HTTP/1.1 200 OK\\r\\nContent-Length: ".length($b)."\\r\\nConnection: close\\r\\n\\r\\n$b";'
" close $c;"
"}"
"' &>/dev/null &"
)
import time; time.sleep(1)
resp = client.get(sbx.get_host(3000), headers=headers)
assert resp.status_code == 200
print(f"get_host(3000): {resp.status_code} body={resp.text!r}")
# get_host(3000): 200 body='port-proxy-ok'
Expected output
envd_api_url: https://api.declaw.ai/sandboxes/sbx-.../...
download_url: https://api.declaw.ai/sandboxes/sbx-.../files/raw?path=...
upload_url: https://api.declaw.ai/sandboxes/sbx-.../files/raw?path=...
get_host(3000): https://api.declaw.ai/sandboxes/sbx-.../ports/3000
get_mcp_url(): https://api.declaw.ai/sandboxes/sbx-.../ports/50005/mcp
Round-trip PASS: 52428800 bytes, sha256 matches.
get_host(3000): 200 body='port-proxy-ok'
Full source
See cookbook/examples/url-helpers/main.py in the repo.