A browser built for agents.
Project description
Rotunda Python
Rotunda gives Python agents a Playwright-compatible browser that is built for real web workflows. It launches the Rotunda Firefox build, creates host-compatible browser fingerprints, and gives each context its own identity without forcing you to manage the browser process by hand.
Use it when you want Playwright ergonomics with a browser that is designed for agent-driven browsing instead of vanilla CDP automation.
Install
pip install -U rotunda
rotunda fetch
Install the GeoIP extra if you use proxies and want Rotunda to align geolocation, timezone, locale, and WebRTC IP with the proxy exit IP:
pip install -U "rotunda[geoip]"
rotunda fetch
If the rotunda console command is not on your path, use python -m rotunda fetch.
Quick Start
from rotunda import NewContext, Rotunda
with Rotunda(headless=False) as browser:
context = NewContext(browser)
page = context.new_page()
page.goto("https://example.com")
print(page.title())
Rotunda(...) launches the browser. NewContext(...) creates a Playwright browser context with a fresh Rotunda fingerprint applied before page scripts run.
Async Usage
import asyncio
from rotunda import AsyncNewContext, AsyncRotunda
async def main():
async with AsyncRotunda(headless=False) as browser:
context = await AsyncNewContext(browser)
page = await context.new_page()
await page.goto("https://example.com")
print(await page.title())
asyncio.run(main())
Playwright-Style Launching
If you already use Playwright directly, keep your existing structure and swap in Rotunda's launch helper:
from playwright.sync_api import sync_playwright
from rotunda import NewBrowser, NewContext
with sync_playwright() as playwright:
browser = NewBrowser(playwright, headless=False)
context = NewContext(browser)
page = context.new_page()
page.goto("https://example.com")
browser.close()
Proxies And GeoIP
Pass proxies in the same shape Playwright expects. With rotunda[geoip], geoip=True derives location data from the current public IP or proxy exit IP.
from rotunda import NewContext, Rotunda
proxy = {
"server": "http://proxy.example:8080",
"username": "user",
"password": "pass",
}
with Rotunda(headless=False, proxy=proxy, geoip=True) as browser:
context = NewContext(browser, proxy=proxy)
page = context.new_page()
page.goto("https://example.com")
You can also set context options yourself:
context = NewContext(
browser,
locale="en-US",
timezone_id="America/New_York",
geolocation={"latitude": 40.7128, "longitude": -74.0060},
)
Headless And Linux Displays
Rotunda defaults to visible browser windows because that best matches agent workflows. On Linux, headless="virtual" starts Rotunda in an Xvfb-backed virtual display:
from rotunda import NewContext, Rotunda
with Rotunda(headless="virtual") as browser:
context = NewContext(browser)
page = context.new_page()
page.goto("https://example.com")
Install xvfb on the host before using virtual display mode.
Reusing A Fingerprint
Most code should let NewContext() generate a fresh identity. If you need the launch fingerprint and context fingerprint to match exactly, generate one fingerprint and pass it to both:
from rotunda import NewContext, Rotunda
from rotunda.fingerprints import generate_fingerprint
fingerprint = generate_fingerprint()
with Rotunda(headless=False, fingerprint=fingerprint) as browser:
context = NewContext(browser, fingerprint=fingerprint)
page = context.new_page()
page.goto("https://example.com")
Debugging A Site
For a quick interactive check, open a Playwright inspector session:
rotunda test https://example.com
For fingerprint reports, enable Rotunda's debug dump around your minimal repro:
export ROTUNDA_DEBUG_DUMP_DIR=/tmp/rotunda-fingerprint-debug
export ROTUNDA_DEBUG_DUMP=manifest,network,console,vm,returns
export ROTUNDA_VM_ACCESS_SAMPLE_RATE=10
python your_repro_script.py
zip -r rotunda-fingerprint-debug.zip "$ROTUNDA_DEBUG_DUMP_DIR"
Review the dump before sharing it. It can include request and response bodies.
Useful CLI Commands
rotunda fetch # install the Rotunda browser used by the Python package
rotunda version # show package, browser, and GeoIP status
rotunda path # print the local Rotunda data directory
rotunda test <url> # open an inspector session for a URL
rotunda remove # remove local Rotunda browser and data files
Local Development
When developing Rotunda itself, point the Python package at a local browser build:
source upstream.sh
export ROTUNDA_EXECUTABLE_PATH="$PWD/rotunda-$version-$release/obj-aarch64-apple-darwin/dist/Rotunda.app/Contents/MacOS/rotunda"
uv run --group dev python -m rotunda test --debug
On Intel macOS, replace obj-aarch64-apple-darwin with obj-x86_64-apple-darwin.
All docs live at rotunda.com/python.
Project details
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 rotunda-0.2.0.tar.gz.
File metadata
- Download URL: rotunda-0.2.0.tar.gz
- Upload date:
- Size: 1.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
338595e387312635b8809fa5d705d92ae92ceb772cd1af83472efc6dc685fc6b
|
|
| MD5 |
85e9168b558cdfc2a63e6f0c3032b6ad
|
|
| BLAKE2b-256 |
3f84681078a774b570bd078e60133d4918d15feeb04dec2a95770d43b06a1b90
|
File details
Details for the file rotunda-0.2.0-py3-none-any.whl.
File metadata
- Download URL: rotunda-0.2.0-py3-none-any.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad9fcec3130e46a62c01e701d965d2aa14091b25c52a5451cd3a66fd26d485c4
|
|
| MD5 |
fd3175c47e5af6780cbfd2d1ce34162b
|
|
| BLAKE2b-256 |
92fe0da7e217eda1fff78c8cbee5f10c79c8042176c50f6de8308d348c86f8f6
|