Skip to main content

pypecdp

Fully async Chrome DevTools Protocol over POSIX pipes with a high-level Browser/Tab/Elem API for Python 3.12+ on Linux.

Chrome automation using --remote-debugging-pipe (no websockets, no ports, just pipes) with bundled CDP protocol classes.

Inspired by playwright-python, python-cdp and nodriver.

Documentation

Full documentation is auto-generated and published at: https://sohaib17.github.io/pypecdp/

Features

  • Fully Async: Built from ground up with asyncio for concurrent operations
  • Fast: Direct pipe communication via file descriptors - no websockets, no network overhead
  • Minimal dependencies: Only one dependency (deprecated) - lightweight and easy to install
  • Secure: Browser only communicates over local pipes, no open ports accessible to other processes
  • No zombies: No risk of orphaned Chrome processes if code crashes - automatic lifecycle management
  • Linux focused: Leverages POSIX pipes and process management

Install

pip install pypecdp

Install Chromium if needed:

# Ubuntu/Debian
sudo apt-get install chromium-browser

# Fedora
sudo dnf install chromium

# Arch
sudo pacman -S chromium

Quick Start

import asyncio
from pypecdp import Browser

async def main():
    # Launch browser
    browser = await Browser.start(
        chrome_path="chromium",
        headless=True
    )
    
    # Navigate to a URL (creates/reuses a tab)
    tab = await browser.navigate("https://example.com")
    
    # Select and interact with elements
    h1 = await tab.wait_for_elem("h1")
    if h1:
        text = await h1.text()
        print(f"Page heading: {text}")
    
    # Evaluate JavaScript
    result = await tab.eval("document.title")
    print(f"Title: {result.value}")
    
    # Close browser
    await browser.close()

asyncio.run(main())

Usage Guide

Browser Management

from pypecdp import Browser, Config

# Simple start
browser = await Browser.start(chrome_path="chromium", headless=True)

# Advanced configuration
config = Config(
    chrome_path="/usr/bin/google-chrome",
    user_data_dir="/tmp/chrome-profile",
    clean_data_dir=False,  # Preserve existing profile data
    headless=True,
    extra_args=["--no-sandbox", "--disable-gpu"],
    env={"LANG": "en_US.UTF-8"}
)
browser = await Browser.start(config=config)

# Close browser
await browser.close()

Note: By default, clean_data_dir=True which removes any existing user data directory before starting. Set it to False to preserve cookies, cache, and other browser state between runs.

Element Interactions

# Finding and clicking elements
button = await tab.wait_for_elem("button.submit")
if button:
    await button.click()

# Clicking elements that cause navigation
link = await tab.wait_for_elem('a[href="/next-page"]')
if link:
    # click() returns the top-level Tab after navigation
    current_tab = await link.click()
    if current_tab:
        # Wait for the new page to load
        await current_tab.wait_for_event(cdp.page.LoadEventFired, timeout=10.0)
        print(f"Navigated to: {current_tab.url}")

Customization via Inheritance

pypecdp is designed to be easily extended through OOP inheritance:

from pypecdp import Browser, Tab, Elem

class MyElem(Elem):
    async def click_and_wait(self, timeout=10.0):
        """Click and wait for page load."""
        tab = await self.click()
        if tab:
            await tab.wait_for_event(cdp.page.LoadEventFired, timeout=timeout)
        return tab

class MyTab(Tab):
    elem_class = MyElem  # Use custom Elem class
    
    async def search(self, query):
        """Custom search method."""
        search_box = await self.wait_for_elem("#search")
        await search_box.type(query)

class MyBrowser(Browser):
    tab_class = MyTab  # Use custom Tab class

# Use your custom classes
browser = await MyBrowser.start()
tab = await browser.navigate("https://example.com")
# tab is now MyTab instance, elements are MyElem instances

See example/customize_pypecdp.py for working example.

Event Handlers

from pypecdp import cdp

# Tab-level events (requires domain enable!)
await tab.send(cdp.runtime.enable())  # Required for runtime events!

async def on_console(event):
    print(f"Console {event.type_}: {event.args}")

tab.on(cdp.runtime.ConsoleAPICalled, on_console)

# Browser-level events
async def on_target_created(event):
    info = event.target_info
    print(f"Target created: {info.type_} - {info.url}")

browser.on(cdp.target.TargetCreated, on_target_created)

Logging

pypecdp uses Python's standard logging module. Configure via environment variables:

# Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
export PYPECDP_LOGLEVEL=DEBUG

# Set custom logger name
export PYPECDP_LOGGER=myapp.browser

Or configure the logger directly in Python:

from pypecdp import logger
import logging

# Set log level
logger.setLevel(logging.DEBUG)

# Add custom handler
handler = logging.FileHandler("pypecdp.log")
logger.addHandler(handler)

Error Handling

try:
    browser = await Browser.start()
    tab = await browser.navigate("https://example.com")
    
    # Your automation code
    elem = await tab.wait_for_elem("button")
    if elem:
        await elem.click()
    
    result = await tab.eval("document.title")
    
except ReferenceError as e:
    # Element's tab is no longer available (closed/detached)
    print(f"Target Error: {e}")
except RuntimeError as e:
    # CDP protocol errors
    print(f"CDP Error: {e}")
except ConnectionError as e:
    # Connection lost
    print(f"Connection Error: {e}")
except Exception as e:
    # Other errors
    print(f"Error: {e}")
finally:
    # Always cleanup
    await browser.close()

Requirements

  • Python 3.12+
  • Linux (uses POSIX pipes and preexec_fn)
  • Chromium or Google Chrome

Links

License

MIT License - See LICENSE file for details.

Contributing

Contributions welcome! This project aims to provide a clean, type-safe interface to Chrome automation on Linux.

Release files for pypecdp 0.6.3

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

Source distribution (sdist)

Source distribution for pypecdp 0.6.3
File Size Uploaded
pypecdp-0.6.3.tar.gz 293.3 kB Details

Built distribution (wheel)

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

Total release size:599.5 kB

Release files / pypecdp-0.6.3.tar.gz

Download URL pypecdp-0.6.3.tar.gz
Size 293.3 kB
Tags Source
SHA-256 checksum
How to use checksums
546e23680fe711d3c1cf5be85519a502f700737dbea53e7f9cea4a026a45201c
BLAKE2b-256 checksum
How to use checksums
695678e48428329b4e935b2aa80256b02130613f65f19888f45d54230f6779a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release files / pypecdp-0.6.3-py3-none-any.whl

Download URL pypecdp-0.6.3-py3-none-any.whl
Size 306.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
578123850cb4587eb3fb519f17d0b7417638b1151f604934b61baf1fe7898c7e
BLAKE2b-256 checksum
How to use checksums
f52d4a815ab31d9e564f705c4ad3dacbdc742fbee22117a5dcc2478c5229f0d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.3 This release

2 release files

0.6.2

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.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