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=Truescreenshots/PDFs, and durably-persisted downloads under one listing). -
Session—navigate,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(passas_artifact=Trueto persist a durableArtifactRefinstead 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
Sessionas a context manager to auto-close. - Downloads:
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d060c290005787c85a4d9c7c66319a053cb98124985d514a69693f091059cdc
|
|
| MD5 |
cebc10c16bf705b03c331d75d12f4caf
|
|
| BLAKE2b-256 |
5863199065970ee57d7ee9e14bc3e79be5fe28b81d840a0cefd06d16362343a7
|
File details
Details for the file agent_browser_control-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agent_browser_control-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c1cea54b2625b93e66f0e8581c67a6f66a4a2907d738fee0f9318296bed9e12
|
|
| MD5 |
3d7bcbb7a5a4c0192aa2c7846945e0c9
|
|
| BLAKE2b-256 |
d27690284f6eb6cea4589535f5a9a0d1efdd6195c4eb52ee447416b51e6f564c
|