Checkout the full documentation here
Currently Hyperbrowser supports creating a browser session in two ways:
- Async Client
- Sync Client
It can be installed from pypi by running :
pip install hyperbrowserThe browser-control examples below also use Playwright:
pip install playwrightBoth the sync and async client follow similar configuration params
The API key can be configured either from the constructor arguments or environment variables using HYPERBROWSER_API_KEY
If no API key is provided, the client falls back to a saved OAuth session created by hx auth login. By default it reads ~/.hx_config/auth/default.json, or ~/.hx_config/auth/<profile>.json when HYPERBROWSER_PROFILE or ClientConfig(profile=...) is set.
Profile names must match ^[A-Za-z0-9._-]+$.
base_url and HYPERBROWSER_BASE_URL accept either https://host or https://host/api. The client normalizes both to the same control-plane base URL.
Hyperbrowser 1.0 accepts plain dictionaries for request parameters. Method
signatures use TypedDict definitions, so editors can autocomplete keys at
every nested level:
fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
# Preferred in 1.0: autocomplete works directly in the dictionary.session=client.sessions.create(
{
"use_stealth": True,
"screen": {"width": 1920, "height": 1080},
}
)Browser sessions can also use an outbound network policy. Omitting these fields keeps the default unrestricted behavior:
session=client.sessions.create(
{
"allow_internet_access": False,
"allow_out": ["example.com"],
"deny_out": ["0.0.0.0/0"],
}
)Direct browser policies accept domains, IPv4 addresses, and CIDR ranges in
allow_out; deny_out accepts IPv4 addresses and CIDR ranges. With a proxy,
allow rules must be domains and the only supported deny rule is 0.0.0.0/0.
Existing Pydantic request classes remain accepted, so upgrading does not require an immediate rewrite:
fromhyperbrowser.modelsimportCreateSessionParams, ScreenConfigsession=client.sessions.create(
CreateSessionParams(
use_stealth=True,
screen=ScreenConfig(width=1920, height=1080),
)
)Import request annotations from hyperbrowser.types when a named variable is
useful. The same names under hyperbrowser.models refer to the legacy Pydantic
request classes. Responses remain Pydantic models.
JSON Schema fields accept raw schema values, including object schemas with
$defs, $ref, or custom keywords, and boolean schemas where the API supports
them. Those schemas and other user-owned mappings are preserved as data; only
SDK-owned request keys are translated to their API aliases. Schema fields
documented as accepting a model class can also generate a schema from a Pydantic
model.
See the Hyperbrowser Python SDK 1.0 migration guide for the complete compatibility details and migration checklist.
importasynciofromhyperbrowserimportAsyncHyperbrowserfromplaywright.async_apiimportasync_playwrightHYPERBROWSER_API_KEY="test-key"asyncdefmain():
asyncwithAsyncHyperbrowser(api_key=HYPERBROWSER_API_KEY) asclient:
session=awaitclient.sessions.create()
try:
asyncwithasync_playwright() asplaywright:
browser=awaitplaywright.chromium.connect_over_cdp(
session.ws_endpoint
)
context=browser.contexts[0]
page=context.pages[0]
print("Navigating to Hacker News...")
awaitpage.goto("https://news.ycombinator.com/")
print("Page title:", awaitpage.title())
finally:
awaitclient.sessions.stop(session.id)
# Run the asyncio event loopasyncio.run(main())fromplaywright.sync_apiimportsync_playwrightfromhyperbrowserimportHyperbrowserHYPERBROWSER_API_KEY="test-key"defmain():
client=Hyperbrowser(api_key=HYPERBROWSER_API_KEY)
session=client.sessions.create()
ws_endpoint=session.ws_endpoint# Launch Playwright and connect to the remote browserwithsync_playwright() asp:
browser=p.chromium.connect_over_cdp(ws_endpoint)
context=browser.new_context()
# Get the first page or create a new oneiflen(context.pages) ==0:
page=context.new_page()
else:
page=context.pages[0]
# Navigate to a websiteprint("Navigating to Hacker News...")
page.goto("https://news.ycombinator.com/")
page_title=page.title()
print("Page title:", page_title)
page.close()
browser.close()
print("Session completed!")
client.sessions.stop(session.id)
# Run the asyncio event loopmain()The sync and async clients expose the same sandbox APIs through client.sandboxes.
fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
sandbox=client.sandboxes.create(
{
"image_name": "node",
"cpu": 2,
"memory_mib": 2048,
"disk_mib": 8192,
"exposed_ports": [{"port": 3000, "auth": True}],
}
)
print(sandbox.exposed_ports[0].browser_url)
print(sandbox.cpu, sandbox.memory_mib, sandbox.disk_mib)
sandbox.stop()
client.close()cpu, memory_mib, and disk_mib are only supported for image launches.
fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
volume=client.volumes.create({"name": "project-cache"})
all_volumes=client.volumes.list()
same_volume=client.volumes.get(volume.id)
sandbox=client.sandboxes.create(
{
"image_name": "node",
"mounts": {
"/workspace/cache": {
"id": same_volume.id,
"type": "rw",
"shared": True,
}
},
}
)
sandbox.stop()
client.volumes.delete(same_volume.id)
client.close()fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
result=client.sandboxes.list(
{
"status": "active",
"search": "sandbox",
"start": 1711929600000,
"end": 1712016000000,
"limit": 20,
}
)
forsandboxinresult.sandboxes:
print(sandbox.id, sandbox.status)fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
snapshots=client.sandboxes.list_snapshots(
{"image_name": "node", "status": "created", "limit": 10}
)fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
sandbox=client.sandboxes.create(
{"image_name": "node", "cpu": 2, "memory_mib": 2048, "disk_mib": 8192}
)
result=sandbox.expose({"port": 8080, "auth": True})
print(result.url, result.browser_url)
sandbox.unexpose(8080)fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
sandbox=client.sandboxes.create({"image_name": "node"})
sandbox.files.write(
[
{
"path": "/tmp/config.json",
"data": '{"debug":true}\n',
"append": True,
"mode": "600",
},
{"path": "/tmp/blob.bin", "data": b"\x00\x01\x02"},
]
)fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
sandbox=client.sandboxes.create({"image_name": "node"})
terminal=sandbox.terminal.create({"command": "bash"})
connection=terminal.attach(cursor=10)
foreventinconnection.events():
print(event)This project is licensed under the MIT License - see the LICENSE file for details.