Getting started with the BAP Python SDK
Install bap-py, connect to a BAP-compatible WebSocket endpoint, and run a session that navigates to a page and reads its title. By the end you'll have a working script and know which connection options control timeouts and transport.
- A Browserless API token from your account dashboard
- Python 3.11 or newer
- A BAP-compatible WebSocket endpoint for your preferred region and browser
- Read the BAP Python SDK overview first if you haven't picked BAP over the GraphQL API or BaaS yet
Get your API token
Copy your token from the account dashboard before continuing. BAP appends it to the endpoint as ?token= when the WebSocket opens, so a missing token fails at connection time rather than on your first method call.
Install the library
python -m pip install bap-py
Connect and run
Swap in your token and this runs as-is:
import bap.sync_api as bap
TOKEN = "YOUR_API_TOKEN_HERE"
# connect() opens no socket. The WebSocket opens when browser.page() is entered.
with bap.Browserless.connect(
browser_ws_endpoint="wss://production-sfo.browserless.io/chromium/bql",
token=TOKEN,
) as browser:
# The context manager closes the page and the browser when the block exits.
with browser.page() as page:
page.goto("https://example.com")
print(page.title())
Expected output
Example Domain
Async applications import bap instead of bap.sync_api. The async API uses the same class and method names with async with and await.
Pick an endpoint
The quickstart uses Chromium. Swap the path for a different browser:
wss://production-sfo.browserless.io/chromium/bql # Chromium, the default
wss://production-sfo.browserless.io/chrome/bql # Google Chrome
wss://production-sfo.browserless.io/stealth/bql # Managed stealth browser
The endpoint must end in /bql. The same host also serves CDP endpoints such as /chromium, and those don't support BAP. See Connection URLs and Endpoints for every region and route.
Connection options
| Option | Type | Default | Description |
|---|---|---|---|
browser_ws_endpoint | str | None | None | BAP-compatible WebSocket endpoint. Optional only when you supply a custom transport that owns its own connection |
token | str | None | None | Your API token. Appended to the endpoint as ?token= when the connection opens |
timeout | float | 30000 | Default per-operation timeout in milliseconds |
transport | Custom transport | Built-in WebSocket transport | Replace the built-in socket with your own transport |
Each call to browser.page() or browser.new_page() opens its own WebSocket connection, so a script that runs three pages holds three sockets until they're closed.
FAQ & Troubleshooting
My connection fails immediately
Check that the endpoint ends in /bql. wss://production-sfo.browserless.io/chromium is a CDP endpoint and won't support BAP. Then confirm your token is set, since it's appended when the socket opens and a missing one fails at connect time.
Why does calling a sync method from my running event loop fail?
Use the async API (import bap) for code that runs on a thread that already owns an event loop, such as inside asyncio or Jupyter. Importing bap.sync_api is fine anywhere. The sync bridge only rejects being called from the thread that owns a running loop, since blocking that thread would deadlock callbacks and network operations.
Do I need to call browser.close()?
No, if you use the with blocks shown above. They close the page and browser sockets automatically when the block exits. Call browser.close() explicitly only if you're managing the browser without context managers, and leaving sessions open holds a browser against your account concurrency until it times out.
Why did my operation time out after 30 seconds?
30000 is the default per-operation timeout, in milliseconds. Raise it globally with timeout on Browserless.connect(), or per call with the timeout keyword that navigation, selector, and CAPTCHA methods accept.