browsa (Python)
Anti-detect browsers for AI agents — official Python SDK for browsa.io.
Install
pip install browsa
Zero dependencies. Pure stdlib. Single-file wheel.
Five-line hello world
from browsa import Client
c = Client(api_key="agt_live_...")
job = c.run_task(
task="Go to news.ycombinator.com and return the top story title.",
llm="claude-opus-4-7",
llm_api_key="sk-ant-...",
)
print(job.final_result)
print("watch live:", job.live_url)
That runs a real Chromium fork (Phantom — our anti-detect browser) inside an isolated burner session, driven by browser-use + Claude Opus. The agent navigates, extracts, and returns. A live noVNC stream URL is available the moment the burner spawns.
Async
import asyncio
from browsa import AsyncClient
async def main():
async with AsyncClient(api_key="agt_live_...") as c:
job = await c.run_task(
task="Scrape the top 5 products on producthunt.com today.",
llm="claude-opus-4-7",
llm_api_key="sk-ant-...",
country="US",
)
print(job.final_result)
asyncio.run(main())
Webhooks
from browsa import webhooks
# In your receiver (Flask/FastAPI/whatever):
ok = webhooks.verify_signature(
body=raw_request_body,
header=request.headers["X-Agents-Signature"],
secret=os.environ["BROWSA_WEBHOOK_SECRET"], # hex-encoded
)
if not ok:
return 401
# Trust the payload only after this point.
What you get
| Capability | Notes |
|---|---|
| Sync + async clients | Client + AsyncClient, same surface |
Real Job envelope |
Typed dataclass + .raw escape hatch |
| Long-poll waits | wait_for_job(timeout=...) uses server-side ?wait=30 |
| Webhook signature verify | HMAC-SHA256, constant-time compare, skew check |
| Canonical error envelope | AuthError, InvalidIDError, RateLimitError, etc. |
X-Request-Id propagation |
Every error carries the server's request id |
| Zero deps | Single wheel, audit-friendly, no transitive surface |
Advanced
Long-running tasks with progress callback
def show(job):
print(f" step {job.step_count}/{job.progress_total} status={job.status}")
job = c.run_task(
task="Open-ended research: scrape arxiv for papers on test-time compute, return top 10 by citation.",
llm="claude-opus-4-7",
llm_api_key="sk-ant-...",
max_steps=80,
on_progress=show,
)
Interactive (input_required) tasks
If your task can pause for human input (captcha, decision point), watch for status input_required and respond:
job = c.create_task(task="...", llm="...", llm_api_key="...")
while not job.is_terminal:
job = c.get_job(job.id, wait=30)
if job.status == "input_required":
answer = input(f"Agent asks: {job.input_question}\n> ")
job = c.respond_to_job(job.id, answer)
JA3-spoofed sessions
Some sites fingerprint TLS handshake shape. Set a profile to spoof macOS Chrome:
job = c.run_task(
task="Go to a TLS-fingerprint-fingerprinted site",
llm="claude-opus-4-7", llm_api_key="sk-...",
ja3_profile="macos_chrome_137", # uses utls
)
Docs
- API reference: https://browsa.io/docs
- Source: https://github.com/mohasaaid/neout/tree/main/sdks/browsa-python
- Issues: https://github.com/mohasaaid/neout/issues
License
MIT.
Release files for browsa 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| browsa-0.1.3.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| browsa-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.7 kB
Release files / browsa-0.1.3.tar.gz
| Download URL | browsa-0.1.3.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3e778cc09c2f09888af51d89618bb06a26d9962f43b965ef5e910a911e0c3eb5
|
|
BLAKE2b-256 checksum How to use checksums |
78895217da8b03e9dc47902e4f9f9ae327a883a90cb7922ff2321ebd596e4d3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / browsa-0.1.3-py3-none-any.whl
| Download URL | browsa-0.1.3-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
93af93058690ca1fd7141a6b11574c15d585437af2494789fa9bb78aef14b033
|
|
BLAKE2b-256 checksum How to use checksums |
84fd6b254f00916e75210cda391fb3b8801aafe447e0e6ac90442590a67319e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|