Skip to content

Repository files navigation

Hyperbrowser Python SDK

Checkout the full documentation here

Installation

Currently Hyperbrowser supports creating a browser session in two ways:

  • Async Client
  • Sync Client

It can be installed from pypi by running :

pip install hyperbrowser

The browser-control examples below also use Playwright:

pip install playwright

Configuration

Both the sync and async client follow similar configuration params

API Key

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.

Usage

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.

Async

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())

Sync

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()

Sandboxes

The sync and async clients expose the same sandbox APIs through client.sandboxes.

Create a sandbox with pre-exposed ports

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.

Manage volumes and mount them in a sandbox

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()

List sandboxes with filters

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)

List snapshots for a specific image

fromhyperbrowserimportHyperbrowserclient=Hyperbrowser(api_key="test-key")
snapshots=client.sandboxes.list_snapshots(
{"image_name": "node", "status": "created", "limit": 10}
)

Expose and unexpose ports

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)

Batch file writes with per-file options

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"},
]
)

Resume terminal output after reconnect

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)

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

24 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages