A type-safe Python client generator for the Chrome DevTools Protocol (CDP). This library automatically generates Python bindings with full TypeScript-like type safety from the official CDP protocol specifications.
TypedDict classes for all CDP commands, parameters, and return typesgit clone https://github.com/browser-use/cdp-use
cd cdp-use
uv sync # or pip install -r requirements.txt
python -m cdp_use.generator
This automatically downloads the latest protocol specifications and generates all type-safe bindings.
import asyncio
from cdp_use.client import CDPClient
async def main():
# Connect to Chrome DevTools
async with CDPClient("ws://localhost:9222/devtools/browser/...") as cdp:
# Get all browser targets with full type safety
targets = await cdp.send.Target.getTargets()
print(f"Found {len(targets['targetInfos'])} targets")
# Navigate to a page
await cdp.send.Page.navigate({"url": "https://example.com"})
asyncio.run(main())
# β
Fully typed parameters
await cdp.send.Runtime.evaluate(params={
"expression": "document.title",
"returnByValue": True
})
# β
Return types are fully typed
result = await cdp.send.DOM.getDocument(params={"depth": 1})
node_id: int = result["root"]["nodeId"] # Full IntelliSense support
# β Type errors caught at development time
await cdp.send.DOM.getDocument(params={"invalid": "param"}) # Type error!
The library provides typesafe event registration with full IDE support:
import asyncio
from cdp_use.client import CDPClient
from cdp_use.cdp.page.events import FrameAttachedEvent, DomContentEventFiredEvent
from cdp_use.cdp.runtime.events import ConsoleAPICalledEvent
from typing import Optional
def on_frame_attached(event: FrameAttachedEvent, session_id: Optional[str]) -> None:
print(f"Frame {event['frameId']} attached to {event['parentFrameId']}")
def on_dom_content_loaded(event: DomContentEventFiredEvent, session_id: Optional[str]) -> None:
print(f"DOM content loaded at: {event['timestamp']}")
def on_console_message(event: ConsoleAPICalledEvent, session_id: Optional[str]) -> None:
print(f"Console: {event['type']}")
async def main():
async with CDPClient("ws://localhost:9222/devtools/page/...") as client:
# Register event handlers with camelCase method names (matching CDP)
client.register.Page.frameAttached(on_frame_attached)
client.register.Page.domContentEventFired(on_dom_content_loaded)
client.register.Runtime.consoleAPICalled(on_console_message)
# Enable domains to start receiving events
await client.send.Page.enable()
await client.send.Runtime.enable()
# Navigate and receive events
await client.send.Page.navigate({"url": "https://example.com"})
await asyncio.sleep(5) # Keep listening for events
β
Type Safety: Event handlers are validated at compile time
β
IDE Support: Full autocomplete for domains and event methods
β
Parameter Validation: Callback signatures are type-checked
β
Event Type Definitions: Each event has its own TypedDict interface
client.register.Domain.eventName(callback_function)
Where:
Domain is any CDP domain (Page, Runtime, Network, etc.)eventName is the camelCase CDP event name (matching CDP specs)callback_function must accept (event_data, session_id) parametersclient.register.Page.* - Page lifecycle, navigation, framesclient.register.Runtime.* - JavaScript execution, console, exceptionsclient.register.Network.* - HTTP requests, responses, WebSocketclient.register.DOM.* - DOM tree changes, attributesclient.register.CSS.* - Stylesheet changes, media queriesclient.register.Debugger.* - Breakpoints, script parsingclient.register.Performance.* - Performance metricsclient.register.Security.* - Security state changesβ Correct Usage:
def handle_console(event: ConsoleAPICalledEvent, session_id: Optional[str]) -> None:
print(f"Console: {event['type']}")
client.register.Runtime.consoleAPICalled(handle_console)
β Type Error - Wrong signature:
def bad_handler(event): # Missing session_id parameter
pass
client.register.Runtime.consoleAPICalled(bad_handler) # Type error!
cdp_use/cdp/
βββ library.py # Main CDPLibrary class
βββ registry.py # Event registry system
βββ registration_library.py # Event registration interface
βββ dom/ # DOM domain
β βββ types.py # DOM-specific types
β βββ commands.py # Command parameter/return types
β βββ events.py # Event types
β βββ library.py # DOMClient class
β βββ registration.py # DOM event registration
βββ page/ # Page domain
β βββ ...
βββ ... (50+ domains total)
class CDPClient:
def __init__(self, url: str):
self.send: CDPLibrary # Send commands
self.register: CDPRegistrationLibrary # Register events
# Domain-specific clients
class CDPLibrary:
def __init__(self, client: CDPClient):
self.DOM = DOMClient(client) # DOM operations
self.Network = NetworkClient(client) # Network monitoring
self.Runtime = RuntimeClient(client) # JavaScript execution
# ... 50+ more domains
# Event registration
class CDPRegistrationLibrary:
def __init__(self, registry: EventRegistry):
self.Page = PageRegistration(registry)
self.Runtime = RuntimeRegistration(registry)
# ... all domains with events
# Using task (recommended)
task generate
# Or directly with uv
uv run python -m cdp_use.generator
# Or with python
python -m cdp_use.generator
This will:
By default, the generator downloads the latest CDP specification from the master branch. To pin a specific version, edit cdp_use/generator/constants.py:
# Pin to a specific commit
CDP_VERSION = "4b0c3f2e8c5d6a7b9e1f2a3c4d5e6f7a8b9c0d1e"
# Or use master for latest
CDP_VERSION = "refs/heads/master"
To find specific commits, visit: https://github.com/ChromeDevTools/devtools-protocol/commits/master
task generate # Regenerate CDP types from protocol definitions
task build # Build the distribution package
task lint # Run ruff linter
task format # Format code with ruff
task format-json # Format JSON protocol files
task example # Run the simple example
task clean # Clean generated files and build artifacts
cdp-use/
βββ cdp_use/
β βββ client.py # Core CDP WebSocket client
β βββ generator/ # Code generation tools
β βββ cdp/ # Generated CDP library (auto-generated)
βββ simple.py # Example usage
βββ README.md
cdp_use/cdp/ directory)python -m cdp_use.generator to regeneratepython simple.pyGenerated from Chrome DevTools Protocol specifications β’ Type-safe β’ Zero runtime overhead
Python
100.0%
A type-safe Python client generator for the Chrome DevTools Protocol (CDP). This library automatically generates Python bindings with full TypeScript-like type safety from the official CDP protocol specifications.
TypedDict classes for all CDP commands, parameters, and return typesgit clone https://github.com/browser-use/cdp-use
cd cdp-use
uv sync # or pip install -r requirements.txt
python -m cdp_use.generator
This automatically downloads the latest protocol specifications and generates all type-safe bindings.
import asyncio
from cdp_use.client import CDPClient
async def main():
# Connect to Chrome DevTools
async with CDPClient("ws://localhost:9222/devtools/browser/...") as cdp:
# Get all browser targets with full type safety
targets = await cdp.send.Target.getTargets()
print(f"Found {len(targets['targetInfos'])} targets")
# Navigate to a page
await cdp.send.Page.navigate({"url": "https://example.com"})
asyncio.run(main())
# β
Fully typed parameters
await cdp.send.Runtime.evaluate(params={
"expression": "document.title",
"returnByValue": True
})
# β
Return types are fully typed
result = await cdp.send.DOM.getDocument(params={"depth": 1})
node_id: int = result["root"]["nodeId"] # Full IntelliSense support
# β Type errors caught at development time
await cdp.send.DOM.getDocument(params={"invalid": "param"}) # Type error!
The library provides typesafe event registration with full IDE support:
import asyncio
from cdp_use.client import CDPClient
from cdp_use.cdp.page.events import FrameAttachedEvent, DomContentEventFiredEvent
from cdp_use.cdp.runtime.events import ConsoleAPICalledEvent
from typing import Optional
def on_frame_attached(event: FrameAttachedEvent, session_id: Optional[str]) -> None:
print(f"Frame {event['frameId']} attached to {event['parentFrameId']}")
def on_dom_content_loaded(event: DomContentEventFiredEvent, session_id: Optional[str]) -> None:
print(f"DOM content loaded at: {event['timestamp']}")
def on_console_message(event: ConsoleAPICalledEvent, session_id: Optional[str]) -> None:
print(f"Console: {event['type']}")
async def main():
async with CDPClient("ws://localhost:9222/devtools/page/...") as client:
# Register event handlers with camelCase method names (matching CDP)
client.register.Page.frameAttached(on_frame_attached)
client.register.Page.domContentEventFired(on_dom_content_loaded)
client.register.Runtime.consoleAPICalled(on_console_message)
# Enable domains to start receiving events
await client.send.Page.enable()
await client.send.Runtime.enable()
# Navigate and receive events
await client.send.Page.navigate({"url": "https://example.com"})
await asyncio.sleep(5) # Keep listening for events
β
Type Safety: Event handlers are validated at compile time
β
IDE Support: Full autocomplete for domains and event methods
β
Parameter Validation: Callback signatures are type-checked
β
Event Type Definitions: Each event has its own TypedDict interface
client.register.Domain.eventName(callback_function)
Where:
Domain is any CDP domain (Page, Runtime, Network, etc.)eventName is the camelCase CDP event name (matching CDP specs)callback_function must accept (event_data, session_id) parametersclient.register.Page.* - Page lifecycle, navigation, framesclient.register.Runtime.* - JavaScript execution, console, exceptionsclient.register.Network.* - HTTP requests, responses, WebSocketclient.register.DOM.* - DOM tree changes, attributesclient.register.CSS.* - Stylesheet changes, media queriesclient.register.Debugger.* - Breakpoints, script parsingclient.register.Performance.* - Performance metricsclient.register.Security.* - Security state changesβ Correct Usage:
def handle_console(event: ConsoleAPICalledEvent, session_id: Optional[str]) -> None:
print(f"Console: {event['type']}")
client.register.Runtime.consoleAPICalled(handle_console)
β Type Error - Wrong signature:
def bad_handler(event): # Missing session_id parameter
pass
client.register.Runtime.consoleAPICalled(bad_handler) # Type error!
cdp_use/cdp/
βββ library.py # Main CDPLibrary class
βββ registry.py # Event registry system
βββ registration_library.py # Event registration interface
βββ dom/ # DOM domain
β βββ types.py # DOM-specific types
β βββ commands.py # Command parameter/return types
β βββ events.py # Event types
β βββ library.py # DOMClient class
β βββ registration.py # DOM event registration
βββ page/ # Page domain
β βββ ...
βββ ... (50+ domains total)
class CDPClient:
def __init__(self, url: str):
self.send: CDPLibrary # Send commands
self.register: CDPRegistrationLibrary # Register events
# Domain-specific clients
class CDPLibrary:
def __init__(self, client: CDPClient):
self.DOM = DOMClient(client) # DOM operations
self.Network = NetworkClient(client) # Network monitoring
self.Runtime = RuntimeClient(client) # JavaScript execution
# ... 50+ more domains
# Event registration
class CDPRegistrationLibrary:
def __init__(self, registry: EventRegistry):
self.Page = PageRegistration(registry)
self.Runtime = RuntimeRegistration(registry)
# ... all domains with events
# Using task (recommended)
task generate
# Or directly with uv
uv run python -m cdp_use.generator
# Or with python
python -m cdp_use.generator
This will:
By default, the generator downloads the latest CDP specification from the master branch. To pin a specific version, edit cdp_use/generator/constants.py:
# Pin to a specific commit
CDP_VERSION = "4b0c3f2e8c5d6a7b9e1f2a3c4d5e6f7a8b9c0d1e"
# Or use master for latest
CDP_VERSION = "refs/heads/master"
To find specific commits, visit: https://github.com/ChromeDevTools/devtools-protocol/commits/master
task generate # Regenerate CDP types from protocol definitions
task build # Build the distribution package
task lint # Run ruff linter
task format # Format code with ruff
task format-json # Format JSON protocol files
task example # Run the simple example
task clean # Clean generated files and build artifacts
cdp-use/
βββ cdp_use/
β βββ client.py # Core CDP WebSocket client
β βββ generator/ # Code generation tools
β βββ cdp/ # Generated CDP library (auto-generated)
βββ simple.py # Example usage
βββ README.md
cdp_use/cdp/ directory)python -m cdp_use.generator to regeneratepython simple.pyGenerated from Chrome DevTools Protocol specifications β’ Type-safe β’ Zero runtime overhead
Python
100.0%