cdp-connect-kit 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cdp_connect_kit-0.3.1/.github/workflows/ci.yml +31 -0
- cdp_connect_kit-0.3.1/.github/workflows/release.yml +54 -0
- cdp_connect_kit-0.3.1/.gitignore +12 -0
- cdp_connect_kit-0.3.1/CHANGELOG.md +51 -0
- cdp_connect_kit-0.3.1/LICENSE +21 -0
- cdp_connect_kit-0.3.1/PKG-INFO +245 -0
- cdp_connect_kit-0.3.1/README.md +208 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/__init__.py +15 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/__init__.py +14 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/client.py +105 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/models.py +43 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/url.py +77 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/cli.py +211 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/connect.py +97 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/deal.py +25 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/mlx.py +367 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/mlx_cli.py +142 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/retry.py +45 -0
- cdp_connect_kit-0.3.1/cdp_connect_kit/watch.py +66 -0
- cdp_connect_kit-0.3.1/docs/AFFILIATE.md +58 -0
- cdp_connect_kit-0.3.1/docs/ENV.md +36 -0
- cdp_connect_kit-0.3.1/docs/FAQ.md +33 -0
- cdp_connect_kit-0.3.1/docs/MLX_INTEGRATION.md +193 -0
- cdp_connect_kit-0.3.1/docs/MLX_LAUNCHER.md +104 -0
- cdp_connect_kit-0.3.1/pyproject.toml +83 -0
- cdp_connect_kit-0.3.1/tests/test_cdp_client.py +43 -0
- cdp_connect_kit-0.3.1/tests/test_cdp_url.py +44 -0
- cdp_connect_kit-0.3.1/tests/test_cli.py +77 -0
- cdp_connect_kit-0.3.1/tests/test_connect.py +36 -0
- cdp_connect_kit-0.3.1/tests/test_integration_cdp.py +44 -0
- cdp_connect_kit-0.3.1/tests/test_mlx.py +219 -0
- cdp_connect_kit-0.3.1/tests/test_mlx_cli.py +108 -0
- cdp_connect_kit-0.3.1/tests/test_retry.py +35 -0
- cdp_connect_kit-0.3.1/tests/test_watch.py +49 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
|
|
21
|
+
- name: Install package and dev deps
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
playwright install chromium
|
|
26
|
+
|
|
27
|
+
- name: Ruff
|
|
28
|
+
run: ruff check .
|
|
29
|
+
|
|
30
|
+
- name: Pytest
|
|
31
|
+
run: pytest
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Set up Python 3.12
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
|
|
19
|
+
- name: Install package and dev deps
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
pip install -e ".[dev]"
|
|
23
|
+
playwright install chromium
|
|
24
|
+
|
|
25
|
+
- name: Ruff
|
|
26
|
+
run: ruff check .
|
|
27
|
+
|
|
28
|
+
- name: Pytest
|
|
29
|
+
run: pytest
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
needs: test
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Set up Python 3.12
|
|
38
|
+
uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.12"
|
|
41
|
+
|
|
42
|
+
- name: Install build tools
|
|
43
|
+
run: python -m pip install --upgrade pip build twine
|
|
44
|
+
|
|
45
|
+
- name: Build
|
|
46
|
+
run: python -m build
|
|
47
|
+
|
|
48
|
+
- name: Twine check
|
|
49
|
+
run: twine check dist/*
|
|
50
|
+
|
|
51
|
+
- name: Publish to PyPI
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
53
|
+
with:
|
|
54
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.3.1 — 2026-06-11
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- PyPI README: SEO subtitle (connect_over_cdp + MLX Launcher), CDP failure playbook, contextual affiliate note
|
|
8
|
+
- `pyproject.toml`: keywords (`playwright-connect-over-cdp`, `multilogin-launcher`)
|
|
9
|
+
- `--show-deal`: contextual Launcher CDP copy with affiliate disclosure
|
|
10
|
+
- FAQ: +3 SEO questions (connect_over_cdp, farm health-check, affiliate opt-in)
|
|
11
|
+
|
|
12
|
+
## v0.3.0 — 2026-06-11
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `mlx-list` — list running Launcher sessions (`/api/v2/profile/active`)
|
|
17
|
+
- `mlx-start --print-cdp-url` — CDP HTTP URL on stdout for shell scripting
|
|
18
|
+
- `mlx-start --wait-timeout` (default 120s) — poll CDP until ready
|
|
19
|
+
- `mlx-start --connect` — optional Playwright connect + metrics JSON
|
|
20
|
+
- `MlxLauncher.list_running_sessions()`, `start_profile_and_wait()`, `wait_for_cdp()`
|
|
21
|
+
- Already-running profile reuse via active-session lookup
|
|
22
|
+
- Idempotent `mlx-stop` (default); `--strict` for hard errors
|
|
23
|
+
- `MLX_LAUNCHER_URL` env (preferred over `MLX_LAUNCHER_HOST`)
|
|
24
|
+
- `docs/MLX_INTEGRATION.md` — definitive monorepo MLX bridge guide
|
|
25
|
+
- 15+ mocked MLX unit/CLI tests (timeout, already running, idempotent stop)
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- `mlx-start` no longer connects Playwright unless `--connect` is passed
|
|
30
|
+
- MLX CLI logic moved to `cdp_connect_kit.mlx_cli`
|
|
31
|
+
|
|
32
|
+
## v0.2.0 — 2026-06-11
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- Robust CDP URL parser: `http://`, `https://`, `ws://`, `wss://`, `host:port` (default port **9222**)
|
|
37
|
+
- `watch` emits **JSON Lines** (`--format jsonl`, default) for piping to farm-runner
|
|
38
|
+
- Exponential backoff retries (`--max-retries` on `playwright` and `mlx-start`)
|
|
39
|
+
- Integration test with mocked `/json/version` (no real browser)
|
|
40
|
+
- README mermaid sequence: MLX Launcher → CDP URL → Playwright
|
|
41
|
+
- `docs/ENV.md` — `MLX_TOKEN`, `MLX_LAUNCHER_HOST`, `MLX_FOLDER_ID`
|
|
42
|
+
- GitHub Actions CI (Python 3.10–3.12)
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- `watch --format plain` restores human-readable `UP`/`DOWN` lines
|
|
47
|
+
- `MlxLauncher` reads `MLX_LAUNCHER_HOST` when `--launcher-host` is omitted
|
|
48
|
+
|
|
49
|
+
## v0.1.0 — 2026-06-01
|
|
50
|
+
|
|
51
|
+
- Initial release: CDP ping, Playwright connect, watch, MLX launcher helpers
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 cdp-connect-kit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cdp-connect-kit
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Playwright connect_over_cdp — parse endpoints, MLX Launcher start, CDP health + retry. CLI: cdp-connect.
|
|
5
|
+
Project-URL: Homepage, https://github.com/cdp-connect-kit/cdp-connect-kit
|
|
6
|
+
Project-URL: Documentation, https://github.com/cdp-connect-kit/cdp-connect-kit#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/cdp-connect-kit/cdp-connect-kit
|
|
8
|
+
Project-URL: Issues, https://github.com/cdp-connect-kit/cdp-connect-kit/issues
|
|
9
|
+
Author: cdp-connect-kit contributors
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: antidetect-cdp,browser-debugging,cdp-connect,cdp-endpoint,cdp-health,cdp-retry,chrome-devtools-protocol,connect-over-cdp,devtools-websocket,endpoint-watch,mlx-start,multilogin-launcher,playwright-cdp,playwright-connect-over-cdp,remote-debugging
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
|
|
23
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: click>=8.1
|
|
27
|
+
Requires-Dist: playwright>=1.40
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
34
|
+
Provides-Extra: mlx
|
|
35
|
+
Requires-Dist: httpx>=0.27; extra == 'mlx'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# cdp-connect-kit
|
|
39
|
+
|
|
40
|
+
**Playwright connect_over_cdp kit** — parse MLX Launcher ports, health-check CDP, retry Playwright attach with metrics.
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
43
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
44
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install cdp-connect-kit
|
|
48
|
+
cdp-connect ping 127.0.0.1:9222
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
CLI: **`cdp-connect`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
52
|
+
|
|
53
|
+
**CDP connection toolkit** — parse Chrome DevTools Protocol endpoints, validate WebSocket URLs, connect Playwright with **retry + timeout + health metrics**, and watch endpoint uptime.
|
|
54
|
+
|
|
55
|
+
Optional `[mlx]` extra: start Multilogin X profiles via Launcher API → auto `connect_over_cdp`.
|
|
56
|
+
|
|
57
|
+
## Problem
|
|
58
|
+
|
|
59
|
+
Connecting Playwright to a remote or antidetect browser over CDP fails for predictable reasons:
|
|
60
|
+
|
|
61
|
+
- Wrong URL shape (`ws://` vs `http://127.0.0.1:PORT`)
|
|
62
|
+
- Browser not finished starting
|
|
63
|
+
- Fragile one-shot `connect_over_cdp` with no metrics
|
|
64
|
+
|
|
65
|
+
`cdp-connect` normalizes endpoints, waits for `/json/version`, retries connections, and reports health.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install cdp-connect-kit
|
|
71
|
+
playwright install chromium
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
MLX Launcher integration:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install cdp-connect-kit[mlx]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Quick start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Ping a CDP endpoint (HTTP or WebSocket URL)
|
|
84
|
+
cdp-connect ping ws://127.0.0.1:9222/devtools/browser/abc
|
|
85
|
+
|
|
86
|
+
# Connect Playwright and screenshot
|
|
87
|
+
cdp-connect playwright --endpoint http://127.0.0.1:9222 --screenshot out.png
|
|
88
|
+
|
|
89
|
+
# Watch health — JSON Lines for farm-runner piping
|
|
90
|
+
cdp-connect watch --endpoint 127.0.0.1:9222 --interval 5 | tee health.jsonl
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Connection flow
|
|
94
|
+
|
|
95
|
+
```mermaid
|
|
96
|
+
sequenceDiagram
|
|
97
|
+
participant MLX as MLX Launcher
|
|
98
|
+
participant CDP as CDP HTTP :PORT
|
|
99
|
+
participant PW as Playwright
|
|
100
|
+
|
|
101
|
+
MLX->>MLX: GET /profile/.../start
|
|
102
|
+
MLX-->>CDP: data.port → http://127.0.0.1:PORT
|
|
103
|
+
PW->>CDP: GET /json/version
|
|
104
|
+
CDP-->>PW: webSocketDebuggerUrl
|
|
105
|
+
PW->>PW: connect_over_cdp(http://127.0.0.1:PORT)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## CLI
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---------|-------------|
|
|
112
|
+
| `cdp-connect ping ENDPOINT` | Validate `/json/version`, print WebSocket URL |
|
|
113
|
+
| `cdp-connect playwright --endpoint URL [--screenshot FILE]` | Connect with retry, emit metrics JSON |
|
|
114
|
+
| `cdp-connect watch --endpoint URL` | Poll health as **JSON Lines** (default) |
|
|
115
|
+
| `cdp-connect watch --format plain` | Human-readable `UP`/`DOWN` lines |
|
|
116
|
+
| `cdp-connect playwright --max-retries N` | Connect with exponential backoff |
|
|
117
|
+
| `cdp-connect mlx-start --profile-id UUID [--print-cdp-url]` | Start MLX profile, wait for CDP (`[mlx]`) |
|
|
118
|
+
| `cdp-connect mlx-stop --profile-id UUID` | Stop MLX profile — idempotent (`[mlx]`) |
|
|
119
|
+
| `cdp-connect mlx-list` | List running Launcher sessions (`[mlx]`) |
|
|
120
|
+
|
|
121
|
+
**Endpoint formats:** `http://127.0.0.1:9222`, `ws://127.0.0.1:9222/devtools/browser/…`, `127.0.0.1:9222` (shorthand; default port 9222).
|
|
122
|
+
|
|
123
|
+
### MLX launcher flow
|
|
124
|
+
|
|
125
|
+
1. `GET launcher.mlx.yt:45001/api/v2/profile/f/{folder}/p/{profile}/start?automation_type=playwright`
|
|
126
|
+
2. Read `data.port` from JSON response
|
|
127
|
+
3. CDP HTTP base = `http://127.0.0.1:{port}`
|
|
128
|
+
4. `GET /json/version` → `webSocketDebuggerUrl`
|
|
129
|
+
5. `playwright.chromium.connect_over_cdp(http://127.0.0.1:{port})`
|
|
130
|
+
|
|
131
|
+
**Canonical MLX bridge for the monorepo:** [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md) · Env: [docs/ENV.md](docs/ENV.md)
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
export MLX_TOKEN="..."
|
|
135
|
+
export MLX_FOLDER_ID="..."
|
|
136
|
+
export MLX_LAUNCHER_URL="https://launcher.mlx.yt:45001" # optional
|
|
137
|
+
|
|
138
|
+
# Scripting: CDP URL on stdout
|
|
139
|
+
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
|
|
140
|
+
|
|
141
|
+
cdp-connect mlx-list
|
|
142
|
+
cdp-connect mlx-stop --profile-id PROFILE_UUID
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## API
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from cdp_connect_kit import CdpClient, connect_playwright, parse_endpoint
|
|
149
|
+
import asyncio
|
|
150
|
+
|
|
151
|
+
async def main():
|
|
152
|
+
client = CdpClient("127.0.0.1:9222")
|
|
153
|
+
print(client.resolve_websocket_url())
|
|
154
|
+
browser, pw, metrics = await connect_playwright("127.0.0.1:9222", max_retries=5)
|
|
155
|
+
print(metrics.to_dict())
|
|
156
|
+
await browser.close()
|
|
157
|
+
await pw.stop()
|
|
158
|
+
|
|
159
|
+
asyncio.run(main())
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Symbol | Description |
|
|
163
|
+
|--------|-------------|
|
|
164
|
+
| `parse_endpoint(url)` | Normalize HTTP / WS / host:port |
|
|
165
|
+
| `CdpClient` | `/json/version`, `/json/list`, `health_snapshot()` |
|
|
166
|
+
| `connect_playwright(endpoint)` | Retry wrapper → `(browser, playwright, ConnectMetrics)` |
|
|
167
|
+
| `watch_endpoint(endpoint)` | Async health polling |
|
|
168
|
+
|
|
169
|
+
### ConnectMetrics
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"endpoint": "http://127.0.0.1:9222",
|
|
174
|
+
"web_socket_url": "ws://127.0.0.1:9222/devtools/browser/...",
|
|
175
|
+
"attempts": 1,
|
|
176
|
+
"connect_ms": 842.1,
|
|
177
|
+
"ready_ms": 120.5,
|
|
178
|
+
"target_count": 3
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## When `connect_over_cdp` keeps failing (playbook)
|
|
183
|
+
|
|
184
|
+
Most failures are **endpoint shape** or **browser not ready** — not Playwright bugs.
|
|
185
|
+
|
|
186
|
+
| Error pattern | Likely cause | Fix |
|
|
187
|
+
|---------------|--------------|-----|
|
|
188
|
+
| `Connection refused` | Port not open yet | `cdp-connect ping` in a loop; MLX: `mlx-start --wait-timeout` |
|
|
189
|
+
| `Invalid URL` / WS mismatch | Passed raw `ws://…` without version fetch | Use HTTP base `http://127.0.0.1:PORT`; let client resolve WS |
|
|
190
|
+
| Works once, flaky in farm | Race on profile start | `watch --endpoint URL` → JSONL for `farm-runner`; retry `connect_playwright` |
|
|
191
|
+
| Chrome 136+ local profile | Default `user-data-dir` blocks CDP | Custom profile dir or antidetect Launcher port |
|
|
192
|
+
| MLX 401 / timeout | Agent not running or wrong token | `MLX_TOKEN`, desktop agent up; see `docs/ENV.md` |
|
|
193
|
+
|
|
194
|
+
**MLX → Playwright pipeline:**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
export MLX_TOKEN=... MLX_FOLDER_ID=...
|
|
198
|
+
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
|
|
199
|
+
cdp-connect ping "$CDP_URL"
|
|
200
|
+
cdp-connect playwright --endpoint "$CDP_URL" --max-retries 5
|
|
201
|
+
# farm scripts: export CDP_URL for child processes
|
|
202
|
+
cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com
|
|
203
|
+
cdp-connect mlx-stop --profile-id PROFILE_UUID
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Canonical API details: [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md).
|
|
207
|
+
|
|
208
|
+
## Limitations
|
|
209
|
+
|
|
210
|
+
- **Chromium CDP only** — `connect_over_cdp` targets Chromium-based browsers.
|
|
211
|
+
- **MLX requires local agent** — Launcher API needs Multilogin desktop running.
|
|
212
|
+
- **Watch mode** uses HTTP discovery only; JSONL output is designed for `automation-farm-runner` ingestion.
|
|
213
|
+
- **Not a fingerprint tool** — connects to browsers; does not modify profiles.
|
|
214
|
+
|
|
215
|
+
## Production
|
|
216
|
+
|
|
217
|
+
Use `cdp-connect mlx-start` → `connect_playwright` in farm scripts and probes; pair with `farm-runner` (`automation-farm-runner`) for folder pools. Export `CDP_URL` for `human-input-kit` warmup and `playwright-cdp-probe` checks on the same Launcher session.
|
|
218
|
+
|
|
219
|
+
**Partner note (affiliate):** When Playwright must attach to **Multilogin X Launcher** CDP ports (not vanilla `--remote-debugging-port`), isolated profiles are the intended production path. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. `ping` / `playwright` / `watch` work on any CDP server without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `cdp-connect --show-deal` (never printed by default).
|
|
220
|
+
|
|
221
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright connect_over_cdp, Multilogin Launcher, CDP health check.
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
## Related tools (on PyPI)
|
|
228
|
+
|
|
229
|
+
| Package | CLI | Role |
|
|
230
|
+
|---------|-----|------|
|
|
231
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
232
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
233
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
234
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
235
|
+
|
|
236
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
245
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# cdp-connect-kit
|
|
2
|
+
|
|
3
|
+
**Playwright connect_over_cdp kit** — parse MLX Launcher ports, health-check CDP, retry Playwright attach with metrics.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
6
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
7
|
+
[](https://pypi.org/project/cdp-connect-kit/)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install cdp-connect-kit
|
|
11
|
+
cdp-connect ping 127.0.0.1:9222
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
CLI: **`cdp-connect`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
15
|
+
|
|
16
|
+
**CDP connection toolkit** — parse Chrome DevTools Protocol endpoints, validate WebSocket URLs, connect Playwright with **retry + timeout + health metrics**, and watch endpoint uptime.
|
|
17
|
+
|
|
18
|
+
Optional `[mlx]` extra: start Multilogin X profiles via Launcher API → auto `connect_over_cdp`.
|
|
19
|
+
|
|
20
|
+
## Problem
|
|
21
|
+
|
|
22
|
+
Connecting Playwright to a remote or antidetect browser over CDP fails for predictable reasons:
|
|
23
|
+
|
|
24
|
+
- Wrong URL shape (`ws://` vs `http://127.0.0.1:PORT`)
|
|
25
|
+
- Browser not finished starting
|
|
26
|
+
- Fragile one-shot `connect_over_cdp` with no metrics
|
|
27
|
+
|
|
28
|
+
`cdp-connect` normalizes endpoints, waits for `/json/version`, retries connections, and reports health.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install cdp-connect-kit
|
|
34
|
+
playwright install chromium
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
MLX Launcher integration:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install cdp-connect-kit[mlx]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Ping a CDP endpoint (HTTP or WebSocket URL)
|
|
47
|
+
cdp-connect ping ws://127.0.0.1:9222/devtools/browser/abc
|
|
48
|
+
|
|
49
|
+
# Connect Playwright and screenshot
|
|
50
|
+
cdp-connect playwright --endpoint http://127.0.0.1:9222 --screenshot out.png
|
|
51
|
+
|
|
52
|
+
# Watch health — JSON Lines for farm-runner piping
|
|
53
|
+
cdp-connect watch --endpoint 127.0.0.1:9222 --interval 5 | tee health.jsonl
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Connection flow
|
|
57
|
+
|
|
58
|
+
```mermaid
|
|
59
|
+
sequenceDiagram
|
|
60
|
+
participant MLX as MLX Launcher
|
|
61
|
+
participant CDP as CDP HTTP :PORT
|
|
62
|
+
participant PW as Playwright
|
|
63
|
+
|
|
64
|
+
MLX->>MLX: GET /profile/.../start
|
|
65
|
+
MLX-->>CDP: data.port → http://127.0.0.1:PORT
|
|
66
|
+
PW->>CDP: GET /json/version
|
|
67
|
+
CDP-->>PW: webSocketDebuggerUrl
|
|
68
|
+
PW->>PW: connect_over_cdp(http://127.0.0.1:PORT)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## CLI
|
|
72
|
+
|
|
73
|
+
| Command | Description |
|
|
74
|
+
|---------|-------------|
|
|
75
|
+
| `cdp-connect ping ENDPOINT` | Validate `/json/version`, print WebSocket URL |
|
|
76
|
+
| `cdp-connect playwright --endpoint URL [--screenshot FILE]` | Connect with retry, emit metrics JSON |
|
|
77
|
+
| `cdp-connect watch --endpoint URL` | Poll health as **JSON Lines** (default) |
|
|
78
|
+
| `cdp-connect watch --format plain` | Human-readable `UP`/`DOWN` lines |
|
|
79
|
+
| `cdp-connect playwright --max-retries N` | Connect with exponential backoff |
|
|
80
|
+
| `cdp-connect mlx-start --profile-id UUID [--print-cdp-url]` | Start MLX profile, wait for CDP (`[mlx]`) |
|
|
81
|
+
| `cdp-connect mlx-stop --profile-id UUID` | Stop MLX profile — idempotent (`[mlx]`) |
|
|
82
|
+
| `cdp-connect mlx-list` | List running Launcher sessions (`[mlx]`) |
|
|
83
|
+
|
|
84
|
+
**Endpoint formats:** `http://127.0.0.1:9222`, `ws://127.0.0.1:9222/devtools/browser/…`, `127.0.0.1:9222` (shorthand; default port 9222).
|
|
85
|
+
|
|
86
|
+
### MLX launcher flow
|
|
87
|
+
|
|
88
|
+
1. `GET launcher.mlx.yt:45001/api/v2/profile/f/{folder}/p/{profile}/start?automation_type=playwright`
|
|
89
|
+
2. Read `data.port` from JSON response
|
|
90
|
+
3. CDP HTTP base = `http://127.0.0.1:{port}`
|
|
91
|
+
4. `GET /json/version` → `webSocketDebuggerUrl`
|
|
92
|
+
5. `playwright.chromium.connect_over_cdp(http://127.0.0.1:{port})`
|
|
93
|
+
|
|
94
|
+
**Canonical MLX bridge for the monorepo:** [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md) · Env: [docs/ENV.md](docs/ENV.md)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
export MLX_TOKEN="..."
|
|
98
|
+
export MLX_FOLDER_ID="..."
|
|
99
|
+
export MLX_LAUNCHER_URL="https://launcher.mlx.yt:45001" # optional
|
|
100
|
+
|
|
101
|
+
# Scripting: CDP URL on stdout
|
|
102
|
+
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
|
|
103
|
+
|
|
104
|
+
cdp-connect mlx-list
|
|
105
|
+
cdp-connect mlx-stop --profile-id PROFILE_UUID
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## API
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from cdp_connect_kit import CdpClient, connect_playwright, parse_endpoint
|
|
112
|
+
import asyncio
|
|
113
|
+
|
|
114
|
+
async def main():
|
|
115
|
+
client = CdpClient("127.0.0.1:9222")
|
|
116
|
+
print(client.resolve_websocket_url())
|
|
117
|
+
browser, pw, metrics = await connect_playwright("127.0.0.1:9222", max_retries=5)
|
|
118
|
+
print(metrics.to_dict())
|
|
119
|
+
await browser.close()
|
|
120
|
+
await pw.stop()
|
|
121
|
+
|
|
122
|
+
asyncio.run(main())
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Symbol | Description |
|
|
126
|
+
|--------|-------------|
|
|
127
|
+
| `parse_endpoint(url)` | Normalize HTTP / WS / host:port |
|
|
128
|
+
| `CdpClient` | `/json/version`, `/json/list`, `health_snapshot()` |
|
|
129
|
+
| `connect_playwright(endpoint)` | Retry wrapper → `(browser, playwright, ConnectMetrics)` |
|
|
130
|
+
| `watch_endpoint(endpoint)` | Async health polling |
|
|
131
|
+
|
|
132
|
+
### ConnectMetrics
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"endpoint": "http://127.0.0.1:9222",
|
|
137
|
+
"web_socket_url": "ws://127.0.0.1:9222/devtools/browser/...",
|
|
138
|
+
"attempts": 1,
|
|
139
|
+
"connect_ms": 842.1,
|
|
140
|
+
"ready_ms": 120.5,
|
|
141
|
+
"target_count": 3
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## When `connect_over_cdp` keeps failing (playbook)
|
|
146
|
+
|
|
147
|
+
Most failures are **endpoint shape** or **browser not ready** — not Playwright bugs.
|
|
148
|
+
|
|
149
|
+
| Error pattern | Likely cause | Fix |
|
|
150
|
+
|---------------|--------------|-----|
|
|
151
|
+
| `Connection refused` | Port not open yet | `cdp-connect ping` in a loop; MLX: `mlx-start --wait-timeout` |
|
|
152
|
+
| `Invalid URL` / WS mismatch | Passed raw `ws://…` without version fetch | Use HTTP base `http://127.0.0.1:PORT`; let client resolve WS |
|
|
153
|
+
| Works once, flaky in farm | Race on profile start | `watch --endpoint URL` → JSONL for `farm-runner`; retry `connect_playwright` |
|
|
154
|
+
| Chrome 136+ local profile | Default `user-data-dir` blocks CDP | Custom profile dir or antidetect Launcher port |
|
|
155
|
+
| MLX 401 / timeout | Agent not running or wrong token | `MLX_TOKEN`, desktop agent up; see `docs/ENV.md` |
|
|
156
|
+
|
|
157
|
+
**MLX → Playwright pipeline:**
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
export MLX_TOKEN=... MLX_FOLDER_ID=...
|
|
161
|
+
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
|
|
162
|
+
cdp-connect ping "$CDP_URL"
|
|
163
|
+
cdp-connect playwright --endpoint "$CDP_URL" --max-retries 5
|
|
164
|
+
# farm scripts: export CDP_URL for child processes
|
|
165
|
+
cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com
|
|
166
|
+
cdp-connect mlx-stop --profile-id PROFILE_UUID
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Canonical API details: [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md).
|
|
170
|
+
|
|
171
|
+
## Limitations
|
|
172
|
+
|
|
173
|
+
- **Chromium CDP only** — `connect_over_cdp` targets Chromium-based browsers.
|
|
174
|
+
- **MLX requires local agent** — Launcher API needs Multilogin desktop running.
|
|
175
|
+
- **Watch mode** uses HTTP discovery only; JSONL output is designed for `automation-farm-runner` ingestion.
|
|
176
|
+
- **Not a fingerprint tool** — connects to browsers; does not modify profiles.
|
|
177
|
+
|
|
178
|
+
## Production
|
|
179
|
+
|
|
180
|
+
Use `cdp-connect mlx-start` → `connect_playwright` in farm scripts and probes; pair with `farm-runner` (`automation-farm-runner`) for folder pools. Export `CDP_URL` for `human-input-kit` warmup and `playwright-cdp-probe` checks on the same Launcher session.
|
|
181
|
+
|
|
182
|
+
**Partner note (affiliate):** When Playwright must attach to **Multilogin X Launcher** CDP ports (not vanilla `--remote-debugging-port`), isolated profiles are the intended production path. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. `ping` / `playwright` / `watch` work on any CDP server without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `cdp-connect --show-deal` (never printed by default).
|
|
183
|
+
|
|
184
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright connect_over_cdp, Multilogin Launcher, CDP health check.
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
## Related tools (on PyPI)
|
|
191
|
+
|
|
192
|
+
| Package | CLI | Role |
|
|
193
|
+
|---------|-----|------|
|
|
194
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
195
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
196
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
197
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
198
|
+
|
|
199
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
208
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""CDP connection toolkit with Playwright integration."""
|
|
2
|
+
|
|
3
|
+
from cdp_connect_kit.cdp.client import CdpClient, CdpError
|
|
4
|
+
from cdp_connect_kit.cdp.url import CdpEndpoint, parse_endpoint
|
|
5
|
+
from cdp_connect_kit.connect import ConnectMetrics, connect_playwright
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"CdpClient",
|
|
9
|
+
"CdpEndpoint",
|
|
10
|
+
"CdpError",
|
|
11
|
+
"ConnectMetrics",
|
|
12
|
+
"connect_playwright",
|
|
13
|
+
"parse_endpoint",
|
|
14
|
+
]
|
|
15
|
+
__version__ = "0.3.1"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""CDP HTTP discovery."""
|
|
2
|
+
|
|
3
|
+
from cdp_connect_kit.cdp.client import CdpClient, CdpError
|
|
4
|
+
from cdp_connect_kit.cdp.models import BrowserInfo, HealthSnapshot
|
|
5
|
+
from cdp_connect_kit.cdp.url import CdpEndpoint, parse_endpoint
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"BrowserInfo",
|
|
9
|
+
"CdpClient",
|
|
10
|
+
"CdpEndpoint",
|
|
11
|
+
"CdpError",
|
|
12
|
+
"HealthSnapshot",
|
|
13
|
+
"parse_endpoint",
|
|
14
|
+
]
|