Skip to main content

AgentBrowser — Python SDK

The official Python client for AgentBrowser — a browser that acts on your agents' behalf. Standard library only, zero dependencies. Python 3.8+.

Install

A real, versioned, installable package (pyproject.toml, semantic version in agentbrowser.__version__):

pip install agent-browser-control  # PyPI name (GoodQA #91; import remains `agentbrowser`)
pip install ./sdk/python          # or: pip install -e ./sdk/python for development

Still just one small package if you'd rather vendor it — copy the whole agentbrowser/ directory (not a single file anymore, since __init__.py is now versioned and packaged) into your project:

cp -r sdk/python/agentbrowser your_project/

Quickstart

from agentbrowser import AgentBrowser

ab = AgentBrowser(api_key="gbk_...")            # from the console → API keys

with ab.session(url="https://example.com", record=True) as s:
    png = s.screenshot()                        # -> bytes (PNG)
    pdf = s.pdf()                               # -> bytes (PDF)
    shot = s.screenshot(as_artifact=True)       # -> ArtifactRef (durable)
    data = s.extract_all({"title": "h1", "price": ".price"})
    print(data)                                 # {"title": "...", "price": "..."}
# session auto-closes; because record=True the bundle is persisted server-side

# Use a separate non-recorded session for credentials. Once a hosted credential
# is filled, page, cookie, screenshot, and PDF reads are refused for that session.
with ab.session(url="https://example.com/login") as s:
    s.login("app-login")                        # hosted vault; may await approval
    s.click("#submit")

# Later, fetch the recording:
for rec in ab.recordings():
    open("session.tar.gz", "wb").write(ab.download_recording(rec["id"]))

Bring your own framework (raw CDP)

s = ab.session(cdp=True, url="https://example.com", profile="mobile")
print(s.cdp_url)     # wss://app.getagentbrowser.com/api/sessions/<id>/cdp?ticket=...
# The URL is ready to use — it carries a short-lived ticket scoped to this one
# session, so your account key never ends up in a log. Just:
#   browser = playwright.chromium.connect_over_cdp(s.cdp_url)

The dedicated browser honors url and profile (desktop or mobile) at launch. All hosted traffic is forced through a node-owned public-only proxy that re-resolves and validates every HTTP request and HTTPS tunnel; loopback, private, link-local, metadata, mixed public/private DNS answers, and non-HTTP navigation are rejected. Caller proxy and proxy_bypass options are rejected because they would bypass that boundary. Do not combine cdp=True with record, dom, or no_video; raw-CDP capture is owned by your Playwright/Puppeteer/CDP client.

Use the returned cdp_url unchanged: its ticket is short-lived and scoped to that session. A client that constructs the session CDP endpoint itself must send Authorization: Bearer gbk_... with a key carrying sessions:write. Never append a reusable API key as ?key=.

Structured action output has fixed safety budgets: 1 MiB for snapshot, page text, extraction, evaluation, and cookies; 32 MiB for screenshots; and 64 MiB for PDFs. The service returns a typed 422 action_output_too_large response instead of truncating JSON or binary data. Retry after reducing the requested page/output scope; a 429 action_output_busy means the node's single heavy output slot is occupied and the request should be retried with backoff.

Scheduled jobs & webhooks

ab.create_job(name="price-check", url="https://shop.example/item",
              action="screenshot", interval=3600)          # hourly
ab.create_webhook("https://your-app.com/hooks",
                  events=["job.completed", "session.recording_ready"])

Webhook deliveries are HMAC-signed — verify X-AgentBrowser-Signature (sha256=<hex> over the raw body) with the secret returned on creation.

API surface

  • AgentBrowser(api_key, base_url="https://app.getagentbrowser.com", timeout=75.0)session(), recordings(), download_recording(), delete_recording(), webhooks(), create_webhook(), delete_webhook(), jobs(), create_job(), delete_job(), artifacts(), download_artifact(), delete_artifact() (artifacts covers recordings, as_artifact=True screenshots/PDFs, and durably-persisted downloads under one listing).

  • Sessionnavigate, click, type, select, check, hover, press, scroll, back, forward, reload, click_at, move_to, drag, read_page, extract, extract_all, evaluate, wait_for, snapshot, mark, login, screenshot / pdf (pass as_artifact=True to persist a durable ArtifactRef instead of inlined bytes), get_cookies, set_cookies, set_file_input, share, status, cancel, stream (a generator yielding live NDJSON event envelopes), close, plus:

    • Downloads: wait_for_download, get_download, get_download_info, list_downloads, cancel_download
    • Dialogs: wait_for_dialog, handle_dialog, get_dialog
    • Tabs: tabs, current_tab, switch_tab, new_tab, close_tab, wait_for_popup
    • Network: wait_for_response, get_response_body, block_requests, set_header_overrides, unblock_requests
    • Human takeover: request_human_takeover, resume_from_takeover
    • Storage state: export_storage_state, import_storage_state
    • Any verb the server doesn't yet have a typed wrapper for: act(verb, **params)

    Use Session as a context manager to auto-close.

Errors raise AgentBrowserError (.status, .body, and .code when the server's error body carries a machine-readable one, e.g. action_output_too_large). 500/502 responses from gb-server and gb-noded carry a typed error envelope (see internal/platform/errenvelope.go in the main repo): in addition to .code, AgentBrowserError exposes .retryable (bool — whether the identical request is safe to retry as-is), .request_id and .session_id (correlation ids for support/log grepping), and .details (a dict with error-specific context, e.g. a debug_bundle_id). All four default to False/None for older or not-yet-converted error bodies.

Transport

GET requests (read-only, side-effect-free) automatically retry up to twice with exponential backoff on a connection failure or a 502/503/504.

Session.act() (which every action helper — click, navigate, type, login, ...— goes through) retries the same way, but only when it's provably safe: a read-only verb (extract, screenshot, read_page, ...) retries freely, exactly like a GET. Every other (write) verb retries only behind an idempotency_key — the server (P1-111) caches that action's terminal result per key, so a retried call replays the original result instead of executing again. Pass your own idempotency_key= to act() to control it yourself (e.g. to make your OWN later retry, after your process restarts, safe too); if you don't, act() generates one automatically per call so the built-in retry is never a bare, unprotected write retry.

Every other write (AgentBrowser.session(), create_webhook, create_job, delete_*, ...) is not auto-retried — those endpoints have no idempotency-key support server-side, so retrying one on a transport failure could double-create or double-delete. Session.close() keeps its own narrow, deliberate exception: a second close() call is always safe (a 404 on delete is treated as already-closed).

Pass a per-call timeout= to AgentBrowser._request/_download to override the client's default for one call.

CLI

Installing the package (pip install ./sdk/python) also installs an agentbrowser command — a deterministic way to exercise the hosted API outside an agent, reproduce a failure, or script CI checks.

agentbrowser auth set --api-key gbk_...          # stores ~/.agentbrowser/config.json (0600)
agentbrowser session create --url https://example.com --record --json
agentbrowser session act sess_123 click --param selector=#submit
agentbrowser session act sess_123 type --param selector=#user --param text=me@example.com
agentbrowser session status sess_123
agentbrowser session stream sess_123             # tails live NDJSON events; Ctrl-C to stop
agentbrowser session close sess_123

agentbrowser recording list
agentbrowser recording download rec_123 -o bundle.tar.gz
agentbrowser artifact list                       # recordings + as_artifact screenshots/PDFs + durable downloads
agentbrowser artifact download art_123 -o file.bin
agentbrowser job create --name price-check --url https://shop.example --action screenshot --interval 3600
agentbrowser webhook create --url https://your-app.com/hooks --events job.completed,session.recording_ready

agentbrowser doctor          # config/credentials/connectivity/api-key checks; exits 1 if unhealthy

Every command prints one JSON object to stdout: {"request_id": "...", "ok": true, "data": {...}} on success, {"request_id": "...", "ok": false, "error": "...", "error_code": "..."} on failure (exit code 1). --json gives the compact single-line form for scripts; the default is the same object pretty-printed. request_id is generated client-side per invocation for support correlation — the server doesn't (yet) echo or log it. session stream and ... download -o - are the two exceptions: a live event tail and raw downloaded bytes each print directly to stdout instead of being wrapped in the envelope, since mixing binary/streaming output with a single JSON object on the same stream would corrupt both.

Credentials resolve in order: --api-key/--base-url flags (work before or after the subcommand), AGENTBROWSER_API_KEY/AGENTBROWSER_BASE_URL env vars, then the current (or --profile-named) profile from agentbrowser auth set. agentbrowser profile list / agentbrowser profile use NAME manage multiple stored profiles.

doctor's checks are scoped to what's actually reachable with an API key (config file, credential resolution, /healthz connectivity, and an authenticated recordings:read probe) — node/infra diagnostics need operator-level auth this CLI doesn't have, and aren't attempted. A 401 on the recordings probe is invalid authentication (unhealthy). A 403 is treated as proof the key is valid but missing recordings:read — a warning, so a least-privilege key still exits 0.

Publishing

Release steps (build/verify/twine upload) are documented internally for maintainers, not published here.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_browser_control-0.2.0.tar.gz (36.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_browser_control-0.2.0-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file agent_browser_control-0.2.0.tar.gz.

File metadata

  • Download URL: agent_browser_control-0.2.0.tar.gz
  • Upload date:
  • Size: 36.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.3

File hashes

Hashes for agent_browser_control-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9d060c290005787c85a4d9c7c66319a053cb98124985d514a69693f091059cdc
MD5 cebc10c16bf705b03c331d75d12f4caf
BLAKE2b-256 5863199065970ee57d7ee9e14bc3e79be5fe28b81d840a0cefd06d16362343a7

See more details on using hashes here.

File details

Details for the file agent_browser_control-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agent_browser_control-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4c1cea54b2625b93e66f0e8581c67a6f66a4a2907d738fee0f9318296bed9e12
MD5 3d7bcbb7a5a4c0192aa2c7846945e0c9
BLAKE2b-256 d27690284f6eb6cea4589535f5a9a0d1efdd6195c4eb52ee447416b51e6f564c

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page