hyperbrowser 1.1.0


pip install hyperbrowser

  Latest version

Released: Jul 30, 2026


Meta
Author: Nikhil Shahi
Requires Python: >=3.8,<4.0

Classifiers

License
  • OSI Approved :: MIT License

Programming Language
  • Python :: 3
  • Python :: 3.8
  • Python :: 3.9
  • Python :: 3.10
  • Python :: 3.11
  • Python :: 3.12
  • Python :: 3.13
  • Python :: 3.14

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:

from hyperbrowser import Hyperbrowser

client = 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:

from hyperbrowser.models import CreateSessionParams, ScreenConfig

session = 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

import asyncio
from hyperbrowser import AsyncHyperbrowser
from playwright.async_api import async_playwright

HYPERBROWSER_API_KEY = "test-key"

async def main():
    async with AsyncHyperbrowser(api_key=HYPERBROWSER_API_KEY) as client:
        session = await client.sessions.create()

        try:
            async with async_playwright() as playwright:
                browser = await playwright.chromium.connect_over_cdp(
                    session.ws_endpoint
                )
                context = browser.contexts[0]
                page = context.pages[0]

                print("Navigating to Hacker News...")
                await page.goto("https://news.ycombinator.com/")
                print("Page title:", await page.title())
        finally:
            await client.sessions.stop(session.id)

# Run the asyncio event loop
asyncio.run(main())

Sync

from playwright.sync_api import sync_playwright
from hyperbrowser import Hyperbrowser

HYPERBROWSER_API_KEY = "test-key"

def main():
    client = Hyperbrowser(api_key=HYPERBROWSER_API_KEY)
    session = client.sessions.create()

    ws_endpoint = session.ws_endpoint

    # Launch Playwright and connect to the remote browser
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(ws_endpoint)
        context = browser.new_context()
        
        # Get the first page or create a new one
        if len(context.pages) == 0:
            page = context.new_page()
        else:
            page = context.pages[0]
        
        # Navigate to a website
        print("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 loop
main()

Sandboxes

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

Create a sandbox with pre-exposed ports

from hyperbrowser import Hyperbrowser

client = 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

from hyperbrowser import Hyperbrowser

client = 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.close()

List sandboxes with filters

from hyperbrowser import Hyperbrowser

client = Hyperbrowser(api_key="test-key")
result = client.sandboxes.list(
    {
        "status": "active",
        "search": "sandbox",
        "start": 1711929600000,
        "end": 1712016000000,
        "limit": 20,
    }
)

for sandbox in result.sandboxes:
    print(sandbox.id, sandbox.status)

List snapshots for a specific image

from hyperbrowser import Hyperbrowser

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

Expose and unexpose ports

from hyperbrowser import Hyperbrowser

client = 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

from hyperbrowser import Hyperbrowser

client = 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

from hyperbrowser import Hyperbrowser

client = Hyperbrowser(api_key="test-key")
sandbox = client.sandboxes.create({"image_name": "node"})
terminal = sandbox.terminal.create({"command": "bash"})

connection = terminal.attach(cursor=10)
for event in connection.events():
    print(event)

License

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

1.1.0 Jul 30, 2026
1.0.0 Jul 25, 2026
0.93.4 Jul 24, 2026
0.93.3 Jul 21, 2026
0.93.2 Jul 12, 2026
0.93.1 Jul 08, 2026
0.93.0 Jul 08, 2026
0.92.3 Jun 30, 2026
0.92.2 Jun 26, 2026
0.92.1 Jun 25, 2026
0.92.0 Jun 16, 2026
0.91.4 Jun 14, 2026
0.91.3 Jun 10, 2026
0.91.2 Jun 01, 2026
0.91.1 May 28, 2026
0.91.0 May 20, 2026
0.90.8 May 08, 2026
0.90.7 May 06, 2026
0.90.6 Apr 28, 2026
0.90.5 Apr 21, 2026
0.90.4 Apr 16, 2026
0.90.3 Apr 14, 2026
0.90.2 Apr 10, 2026
0.90.1 Apr 07, 2026
0.90.0 Apr 06, 2026
0.89.3 Apr 03, 2026
0.89.2 Mar 30, 2026
0.89.1 Mar 27, 2026
0.89.0 Mar 26, 2026
0.88.2 Mar 19, 2026
0.88.1 Mar 18, 2026
0.88.0 Mar 16, 2026
0.87.0 Mar 13, 2026
0.86.0 Mar 12, 2026
0.85.0 Mar 12, 2026
0.84.0 Mar 05, 2026
0.83.3 Feb 18, 2026
0.83.2 Feb 17, 2026
0.83.1 Feb 10, 2026
0.83.0 Feb 08, 2026
0.82.3 Feb 06, 2026
0.82.2 Jan 20, 2026
0.82.1 Jan 18, 2026
0.82.0 Jan 13, 2026
0.81.2 Jan 10, 2026
0.81.1 Jan 09, 2026
0.81.0 Jan 05, 2026
0.80.1 Dec 31, 2025
0.80.0 Dec 30, 2025
0.79.0 Dec 24, 2025
0.78.0 Dec 16, 2025
0.77.0 Dec 16, 2025
0.76.0 Dec 12, 2025
0.75.0 Dec 04, 2025
0.74.1 Nov 25, 2025
0.74.0 Nov 23, 2025
0.73.0 Nov 11, 2025
0.72.0 Nov 08, 2025
0.71.0 Nov 07, 2025
0.70.0 Nov 05, 2025
0.69.0 Oct 29, 2025
0.68.0 Oct 22, 2025
0.67.0 Oct 17, 2025
0.66.0 Oct 16, 2025
0.65.0 Oct 16, 2025
0.64.0 Oct 15, 2025
0.63.0 Oct 15, 2025
0.62.0 Oct 10, 2025
0.61.0 Oct 06, 2025
0.60.0 Oct 03, 2025
0.59.0 Sep 30, 2025
0.58.0 Sep 26, 2025
0.57.0 Sep 19, 2025
0.56.0 Sep 11, 2025
0.55.0 Aug 30, 2025
0.54.0 Aug 25, 2025
0.53.0 Jul 30, 2025
0.52.0 Jul 22, 2025
0.51.0 Jul 15, 2025
0.50.0 Jul 12, 2025
0.49.0 Jul 11, 2025
0.48.0 Jul 07, 2025
0.47.0 Jun 18, 2025
0.46.0 Jun 12, 2025
0.45.1 May 28, 2025
0.45.0 May 28, 2025
0.44.1 May 19, 2025
0.44.0 May 07, 2025
0.43.0 May 07, 2025
0.42.0 May 01, 2025
0.41.0 Apr 21, 2025
0.40.0 Apr 18, 2025
0.39.0 Mar 29, 2025
0.38.0 Mar 19, 2025
0.37.0 Mar 17, 2025
0.36.0 Mar 17, 2025
0.35.0 Mar 17, 2025
0.34.0 Mar 16, 2025
0.33.0 Mar 04, 2025
0.32.0 Mar 03, 2025
0.31.0 Mar 03, 2025
0.30.0 Feb 26, 2025
0.29.0 Feb 15, 2025
0.28.0 Feb 04, 2025
0.27.0 Feb 03, 2025
0.26.0 Feb 03, 2025
0.25.0 Jan 31, 2025
0.24.0 Jan 30, 2025
0.23.0 Jan 27, 2025
0.22.0 Jan 26, 2025
0.21.0 Jan 26, 2025
0.20.0 Jan 25, 2025
0.19.0 Jan 23, 2025
0.18.0 Jan 12, 2025
0.17.0 Jan 10, 2025
0.16.0 Jan 08, 2025
0.15.0 Jan 08, 2025
0.14.0 Jan 05, 2025
0.13.0 Jan 05, 2025
0.12.0 Jan 04, 2025
0.11.0 Dec 31, 2024
0.10.0 Dec 28, 2024
0.9.0 Dec 28, 2024
0.8.0 Dec 24, 2024
0.7.0 Dec 10, 2024
0.6.0 Dec 09, 2024
0.5.0 Dec 05, 2024
0.4.0 Dec 04, 2024
0.3.0 Dec 04, 2024
0.2.0 Dec 04, 2024
0.1.0 Dec 03, 2024

Wheel compatibility matrix

Platform Python 3
any

Files in release

Extras: None
Dependencies:
httpx (<1,>=0.23.0)
jsonref (>=1.1.0)
pydantic (<3,>=2.0)
typing-extensions (<5,>=4.0)
websockets (<16,>=13)