Skip to main content

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.

Rotunda does not install default add-ons unless you ask for them. If a workflow needs the bundled default add-ons, launch with Rotunda(default_addons=True).

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()

Isolated Eval

Rotunda exposes Playwright's isolated utility context when you need custom DOM reads that should avoid page monkeypatches:

from playwright.sync_api import sync_playwright
from rotunda import NewBrowser, NewContext, evaluate_in_utility

with sync_playwright() as playwright:
    browser = NewBrowser(playwright)
    context = NewContext(browser)
    page = context.new_page()
    page.goto("https://example.com")

    title = evaluate_in_utility(page, "() => document.title")

For async code, use async_evaluate_in_utility(page, expression, arg=None). Import rotunda before starting sync_playwright() / async_playwright() so Rotunda can install the Playwright driver preload. Rotunda(...) and AsyncRotunda(...) handle this automatically.

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.

Metadata

Release files for rotunda 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rotunda 0.5.1
File Size Uploaded
rotunda-0.5.1.tar.gz 1.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for rotunda 0.5.1
File Interpreter ABI Platform
rotunda-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 2.8 MB

Release files / rotunda-0.5.1.tar.gz

Download URL rotunda-0.5.1.tar.gz
Size 1.4 MB
Tags Source
SHA-256 checksum
How to use checksums
e425a9c58af2dea2a6e84f0b5d9e0c8493037f295248b1f25a69446a82c34814
BLAKE2b-256 checksum
How to use checksums
37d59d562a7b696117a9bca07ee496a75b36e97bc1a7754b5155017c08de5e7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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}

Release files / rotunda-0.5.1-py3-none-any.whl

Download URL rotunda-0.5.1-py3-none-any.whl
Size 1.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e51bdc5342a71f622d8e1c21b061e823cbde22802ae66c7462e0379e2f2aa582
BLAKE2b-256 checksum
How to use checksums
ad5ac73fd3770a9c811f90249d845f60d7817bfdfff440038167066c2a6ce292
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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}

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 release files

0.4.3

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release 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