session-bundle-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.
- session_bundle_kit-0.3.1/.github/workflows/ci.yml +30 -0
- session_bundle_kit-0.3.1/.github/workflows/release.yml +53 -0
- session_bundle_kit-0.3.1/.gitignore +12 -0
- session_bundle_kit-0.3.1/CHANGELOG.md +46 -0
- session_bundle_kit-0.3.1/LICENSE +21 -0
- session_bundle_kit-0.3.1/PKG-INFO +248 -0
- session_bundle_kit-0.3.1/README.md +213 -0
- session_bundle_kit-0.3.1/docs/AFFILIATE.md +58 -0
- session_bundle_kit-0.3.1/docs/FAQ.md +37 -0
- session_bundle_kit-0.3.1/pyproject.toml +81 -0
- session_bundle_kit-0.3.1/session_bundle_kit/__init__.py +20 -0
- session_bundle_kit-0.3.1/session_bundle_kit/bundle.py +123 -0
- session_bundle_kit-0.3.1/session_bundle_kit/cli.py +189 -0
- session_bundle_kit-0.3.1/session_bundle_kit/deal.py +25 -0
- session_bundle_kit-0.3.1/session_bundle_kit/diff.py +120 -0
- session_bundle_kit-0.3.1/session_bundle_kit/export.py +33 -0
- session_bundle_kit-0.3.1/session_bundle_kit/import_bundle.py +110 -0
- session_bundle_kit-0.3.1/session_bundle_kit/mlx.py +285 -0
- session_bundle_kit-0.3.1/session_bundle_kit/models.py +113 -0
- session_bundle_kit-0.3.1/session_bundle_kit/security.py +38 -0
- session_bundle_kit-0.3.1/tests/fixtures/state.json +25 -0
- session_bundle_kit-0.3.1/tests/fixtures/state_with_secret.json +24 -0
- session_bundle_kit-0.3.1/tests/test_bundle.py +34 -0
- session_bundle_kit-0.3.1/tests/test_cli.py +63 -0
- session_bundle_kit-0.3.1/tests/test_diff.py +47 -0
- session_bundle_kit-0.3.1/tests/test_import.py +25 -0
- session_bundle_kit-0.3.1/tests/test_mlx.py +198 -0
- session_bundle_kit-0.3.1/tests/test_mlx_cli.py +78 -0
- session_bundle_kit-0.3.1/tests/test_roundtrip.py +34 -0
- session_bundle_kit-0.3.1/tests/test_security.py +25 -0
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
|
|
26
|
+
- name: Ruff
|
|
27
|
+
run: ruff check .
|
|
28
|
+
|
|
29
|
+
- name: Pytest
|
|
30
|
+
run: pytest
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
|
|
24
|
+
- name: Ruff
|
|
25
|
+
run: ruff check .
|
|
26
|
+
|
|
27
|
+
- name: Pytest
|
|
28
|
+
run: pytest
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
needs: test
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- name: Set up Python 3.12
|
|
37
|
+
uses: actions/setup-python@v5
|
|
38
|
+
with:
|
|
39
|
+
python-version: "3.12"
|
|
40
|
+
|
|
41
|
+
- name: Install build tools
|
|
42
|
+
run: python -m pip install --upgrade pip build twine
|
|
43
|
+
|
|
44
|
+
- name: Build
|
|
45
|
+
run: python -m build
|
|
46
|
+
|
|
47
|
+
- name: Twine check
|
|
48
|
+
run: twine check dist/*
|
|
49
|
+
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
with:
|
|
53
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.3.1 — 2026-06-11
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- PyPI README: SEO subtitle (Playwright session export), session migration playbook, contextual affiliate note
|
|
8
|
+
- `pyproject.toml`: storage_state / MLX cookie keywords (`playwright-storage-state`, `multilogin-cookies`)
|
|
9
|
+
- `--show-deal`: contextual session-restore copy with affiliate disclosure
|
|
10
|
+
- FAQ: +4 SEO questions (zip backup, MLX import, importer pairing, affiliate opt-in)
|
|
11
|
+
|
|
12
|
+
## v0.3.0 — 2026-06-11
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `session-bundle mlx-pull --profile-id UUID -o bundle.zip` — MLX cookie export → session-bundle-v1
|
|
17
|
+
- `session-bundle mlx-push --dry-run` — validate bundle without Launcher/Cloud API calls
|
|
18
|
+
- `MlxBundleClient.pull_bundle()` / `push_bundle(dry_run=)` with MLX↔Playwright cookie mapping
|
|
19
|
+
- Handles MLX export `cookies` as JSON array or quoted JSON string
|
|
20
|
+
- Mock API tests for pull, push, dry-run, export errors, and CLI
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- `MlxBundlePusher` is an alias for `MlxBundleClient`
|
|
25
|
+
- README: MLX pull/push flow and cdp-connect-kit cross-link
|
|
26
|
+
|
|
27
|
+
## v0.2.0 — 2026-06-11
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Bundle spec **v1**: `manifest.json` with `spec: session-bundle-v1` and `version` field
|
|
32
|
+
- `diff` reports cookie **domains** added / removed / changed
|
|
33
|
+
- `import --dry-run` validates without writing (default; explicit flag documented)
|
|
34
|
+
- Security warnings for plaintext passwords/secrets in `localStorage` / `sessionStorage`
|
|
35
|
+
- Roundtrip test: export fixture → import dry-run
|
|
36
|
+
- README: "When Chrome user-data-dir fails in 2026" (Chrome 136+ policy)
|
|
37
|
+
- GitHub Actions CI (Python 3.10–3.12)
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `ImportReport` includes `warnings` separate from blocking `issues`
|
|
42
|
+
- Manifest read requires `version` field
|
|
43
|
+
|
|
44
|
+
## v0.1.0 — 2026-06-01
|
|
45
|
+
|
|
46
|
+
- Initial release: export/import/diff bundles, optional MLX cookie push
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 session-bundle-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,248 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: session-bundle-kit
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Playwright storage_state zip export — backup sessions, diff bundles, MLX cookie pull/push. CLI: session-bundle.
|
|
5
|
+
Project-URL: Homepage, https://github.com/session-bundle-kit/session-bundle-kit
|
|
6
|
+
Project-URL: Documentation, https://github.com/session-bundle-kit/session-bundle-kit#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/session-bundle-kit/session-bundle-kit
|
|
8
|
+
Project-URL: Issues, https://github.com/session-bundle-kit/session-bundle-kit/issues
|
|
9
|
+
Author: session-bundle-kit contributors
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: browser-backup,browser-session-migration,chrome-136,context-backup,cookie-export,indexeddb-manifest,localstorage-backup,multilogin-cookies,playwright-storage-state,portable-session,session-bundle,session-diff,session-export,session-restore,storage-state,zip-export
|
|
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
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
32
|
+
Provides-Extra: mlx
|
|
33
|
+
Requires-Dist: httpx>=0.27; extra == 'mlx'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# session-bundle-kit
|
|
37
|
+
|
|
38
|
+
**Playwright session export & backup** — zip storage_state cookies and localStorage; MLX cookie pull/push for profile migration.
|
|
39
|
+
|
|
40
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
41
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
42
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install session-bundle-kit
|
|
46
|
+
session-bundle export state.json -o bundle.zip
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
CLI: **`session-bundle`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
50
|
+
|
|
51
|
+
**Playwright session export & backup** — zip `storage_state` cookies and localStorage; MLX cookie pull/push for profile migration.
|
|
52
|
+
|
|
53
|
+
Export and compare **browser session bundles** — cookies, `localStorage`, `sessionStorage`, and IndexedDB metadata — from Playwright storage state JSON.
|
|
54
|
+
|
|
55
|
+
Pure Python zip format. Optional MLX push for cookie import into antidetect profiles.
|
|
56
|
+
|
|
57
|
+
## Problem
|
|
58
|
+
|
|
59
|
+
Playwright `storage_state.json` is a single file mixing cookies and per-origin storage. Teams need:
|
|
60
|
+
|
|
61
|
+
- Portable **zip bundles** with a manifest for CI and backups
|
|
62
|
+
- **Dry-run validation** before restoring sessions
|
|
63
|
+
- **Diff** between two session snapshots
|
|
64
|
+
- Push cookies into **MLX profiles** after export
|
|
65
|
+
|
|
66
|
+
## Install
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install session-bundle-kit
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
MLX profile push:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install session-bundle-kit[mlx]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Quick start
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Export Playwright storage state -> bundle zip
|
|
82
|
+
session-bundle export --playwright-context ./state.json -o bundle.zip
|
|
83
|
+
|
|
84
|
+
# Validate bundle (dry-run default)
|
|
85
|
+
session-bundle import bundle.zip --dry-run
|
|
86
|
+
|
|
87
|
+
# Compare two bundles
|
|
88
|
+
session-bundle diff bundle_a.zip bundle_b.zip
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Bundle format (spec v1)
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
bundle.zip
|
|
95
|
+
├── manifest.json # spec, version, counts, source
|
|
96
|
+
├── cookies.json # Playwright cookie list
|
|
97
|
+
├── origins/
|
|
98
|
+
│ └── https%3A%2F%2Fexample.com.json # localStorage + sessionStorage
|
|
99
|
+
└── indexeddb/
|
|
100
|
+
└── metadata.json # IDB database names/versions (metadata only)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
IndexedDB **metadata** is included for audit/diff; full IDB binary export is out of scope.
|
|
104
|
+
|
|
105
|
+
`manifest.json` example:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"spec": "session-bundle-v1",
|
|
110
|
+
"version": 1,
|
|
111
|
+
"source": "playwright-storage-state",
|
|
112
|
+
"cookie_count": 12,
|
|
113
|
+
"origin_count": 3,
|
|
114
|
+
"indexeddb_count": 0
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## CLI
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
|---------|-------------|
|
|
122
|
+
| `session-bundle export --playwright-context FILE -o OUT.zip` | Create bundle from Playwright state |
|
|
123
|
+
| `session-bundle import FILE --dry-run` | Validate bundle without writing (default) |
|
|
124
|
+
| `session-bundle diff A.zip B.zip` | Cookie domain + storage/IDB diff |
|
|
125
|
+
| `session-bundle mlx-pull --profile-id UUID -o bundle.zip` | Export MLX profile cookies → bundle (`[mlx]`) |
|
|
126
|
+
| `session-bundle mlx-push --profile-id UUID --bundle FILE` | Import bundle cookies to MLX (`[mlx]`) |
|
|
127
|
+
| `session-bundle mlx-push ... --dry-run` | Validate bundle; no MLX API calls |
|
|
128
|
+
|
|
129
|
+
## API
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from session_bundle_kit import export_playwright_context, validate_bundle, diff_bundles
|
|
133
|
+
|
|
134
|
+
export_playwright_context("state.json", "bundle.zip")
|
|
135
|
+
report = validate_bundle("bundle.zip")
|
|
136
|
+
diff = diff_bundles("old.zip", "new.zip")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Restore to Playwright:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from session_bundle_kit.bundle import SessionBundle
|
|
143
|
+
|
|
144
|
+
bundle = SessionBundle.read_zip("bundle.zip")
|
|
145
|
+
context = await browser.new_context(storage_state=bundle.to_playwright_storage_state())
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## MLX pull / push (`[mlx]` extra)
|
|
149
|
+
|
|
150
|
+
Round-trip **cookies** between MLX profiles and neutral **session-bundle-v1** zips. Storage/IDB in bundles from Playwright export are manifest-only on push; MLX Launcher APIs move cookies only.
|
|
151
|
+
|
|
152
|
+
**Pull** (profile → zip):
|
|
153
|
+
|
|
154
|
+
1. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
|
|
155
|
+
2. `POST launcher.mlx.yt:45001/api/v1/cookies/export`
|
|
156
|
+
|
|
157
|
+
**Push** (zip → profile):
|
|
158
|
+
|
|
159
|
+
1. Validate bundle (`--dry-run` stops here)
|
|
160
|
+
2. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
|
|
161
|
+
3. `POST launcher.mlx.yt:45001/api/v1/cookies/import`
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
export MLX_TOKEN="..."
|
|
165
|
+
|
|
166
|
+
# Export MLX profile session to portable bundle
|
|
167
|
+
session-bundle mlx-pull --profile-id PROFILE_UUID -o bundle.zip
|
|
168
|
+
|
|
169
|
+
# Validate before import
|
|
170
|
+
session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip --dry-run
|
|
171
|
+
|
|
172
|
+
# Import cookies into target profile
|
|
173
|
+
session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Peer pattern for Launcher lifecycle: see `cdp-connect-kit` MLX integration docs.
|
|
177
|
+
|
|
178
|
+
## When login sessions break after profile switch (playbook)
|
|
179
|
+
|
|
180
|
+
Sites re-challenge when cookies land on a **new fingerprint or IP**. Use bundles to move **stored** credentials deliberately — not as a bypass.
|
|
181
|
+
|
|
182
|
+
| Symptom | Likely cause | Next step |
|
|
183
|
+
|---------|--------------|-----------|
|
|
184
|
+
| Import ok, still logged out | Domain/subdomain mismatch, expired cookies | `session-bundle diff` old vs new; fix with [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) |
|
|
185
|
+
| Step-up / CAPTCHA after restore | IP or fingerprint drift | Match proxy lane; probe with [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) |
|
|
186
|
+
| MLX push succeeds, site fails | Cookies only — no `localStorage` on target | Restore storage via Playwright `storage_state` on same profile |
|
|
187
|
+
| Migration metadata only | `antidetect-importer` left `_cookies` sidecar | `mlx-pull` source → edit → `mlx-push --dry-run` → push |
|
|
188
|
+
|
|
189
|
+
**Session migration pipeline:**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
session-bundle export --playwright-context state.json -o bundle.zip
|
|
193
|
+
session-bundle import bundle.zip --dry-run
|
|
194
|
+
session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip --dry-run
|
|
195
|
+
export MLX_TOKEN=...
|
|
196
|
+
session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip
|
|
197
|
+
cdp-probe mlx --profile-id TARGET_UUID --url https://your-app.example # verify session + exposure
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Treat bundle zips as **secrets** — same sensitivity as password files.
|
|
201
|
+
|
|
202
|
+
## When Chrome `user-data-dir` fails in 2026
|
|
203
|
+
|
|
204
|
+
Starting with **Chrome 136** (March 2025), Google changed how remote debugging works on the default profile. Per the [Chrome Developers blog](https://developer.chrome.com/blog/remote-debugging-port):
|
|
205
|
+
|
|
206
|
+
- `--remote-debugging-port` and `--remote-debugging-pipe` are **ignored** when targeting Chrome's **default** user data directory.
|
|
207
|
+
- You must pass a **custom** `--user-data-dir` pointing to a non-default profile path for CDP to bind.
|
|
208
|
+
- The change targets cookie theft via remote debugging after [App-Bound Encryption](https://developer.chrome.com/blog/app-bound-encryption); Chrome for Testing still supports the older automation workflow.
|
|
209
|
+
|
|
210
|
+
**Practical impact:** copying your daily `Default` profile and launching with `--remote-debugging-port` no longer works on stock Chrome 136+. Session-bundle-kit sidesteps this by exporting **Playwright `storage_state.json`** (cookies + origin storage) into portable zips — restore via `new_context(storage_state=...)` on antidetect or isolated profiles instead of attaching CDP to your real Chrome profile.
|
|
211
|
+
|
|
212
|
+
Enterprise admins can still control remote debugging via the [Allow remote debugging](https://support.google.com/chrome/a/answer/2657289) Chrome policy on managed devices.
|
|
213
|
+
|
|
214
|
+
## Limitations
|
|
215
|
+
|
|
216
|
+
- **No live IDB export** — IndexedDB section is metadata manifest only.
|
|
217
|
+
- **sessionStorage** preserved in bundle format but Playwright native export may omit it; include in custom state JSON if needed.
|
|
218
|
+
- **mlx-push** imports cookies only; storage must be restored via Playwright or profile sync separately.
|
|
219
|
+
- **Secrets** — bundles contain session secrets; treat zip files as credentials. Import warns on likely plaintext passwords in web storage.
|
|
220
|
+
|
|
221
|
+
## Production
|
|
222
|
+
|
|
223
|
+
Export sessions to portable zips, validate with `mlx-push --dry-run`, then import cookies into MLX profiles after `antidetect-importer` migration or failed login on a new profile.
|
|
224
|
+
|
|
225
|
+
**Partner note (affiliate):** When restoring sessions into **isolated Multilogin X** profiles (not shared Chrome `user-data-dir`), Launcher cookie import pairs with profile-level proxy and fingerprint. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Export/diff/validate work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `session-bundle --show-deal` (never printed by default).
|
|
226
|
+
|
|
227
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright storage_state export, Chrome 136 CDP, MLX cookie import.
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
## Related tools (on PyPI)
|
|
231
|
+
|
|
232
|
+
| Package | CLI | Role |
|
|
233
|
+
|---------|-----|------|
|
|
234
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
235
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
236
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
237
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
238
|
+
|
|
239
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
MIT
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
248
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# session-bundle-kit
|
|
2
|
+
|
|
3
|
+
**Playwright session export & backup** — zip storage_state cookies and localStorage; MLX cookie pull/push for profile migration.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
6
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
7
|
+
[](https://pypi.org/project/session-bundle-kit/)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install session-bundle-kit
|
|
11
|
+
session-bundle export state.json -o bundle.zip
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
CLI: **`session-bundle`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
15
|
+
|
|
16
|
+
**Playwright session export & backup** — zip `storage_state` cookies and localStorage; MLX cookie pull/push for profile migration.
|
|
17
|
+
|
|
18
|
+
Export and compare **browser session bundles** — cookies, `localStorage`, `sessionStorage`, and IndexedDB metadata — from Playwright storage state JSON.
|
|
19
|
+
|
|
20
|
+
Pure Python zip format. Optional MLX push for cookie import into antidetect profiles.
|
|
21
|
+
|
|
22
|
+
## Problem
|
|
23
|
+
|
|
24
|
+
Playwright `storage_state.json` is a single file mixing cookies and per-origin storage. Teams need:
|
|
25
|
+
|
|
26
|
+
- Portable **zip bundles** with a manifest for CI and backups
|
|
27
|
+
- **Dry-run validation** before restoring sessions
|
|
28
|
+
- **Diff** between two session snapshots
|
|
29
|
+
- Push cookies into **MLX profiles** after export
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install session-bundle-kit
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
MLX profile push:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install session-bundle-kit[mlx]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Export Playwright storage state -> bundle zip
|
|
47
|
+
session-bundle export --playwright-context ./state.json -o bundle.zip
|
|
48
|
+
|
|
49
|
+
# Validate bundle (dry-run default)
|
|
50
|
+
session-bundle import bundle.zip --dry-run
|
|
51
|
+
|
|
52
|
+
# Compare two bundles
|
|
53
|
+
session-bundle diff bundle_a.zip bundle_b.zip
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Bundle format (spec v1)
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
bundle.zip
|
|
60
|
+
├── manifest.json # spec, version, counts, source
|
|
61
|
+
├── cookies.json # Playwright cookie list
|
|
62
|
+
├── origins/
|
|
63
|
+
│ └── https%3A%2F%2Fexample.com.json # localStorage + sessionStorage
|
|
64
|
+
└── indexeddb/
|
|
65
|
+
└── metadata.json # IDB database names/versions (metadata only)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
IndexedDB **metadata** is included for audit/diff; full IDB binary export is out of scope.
|
|
69
|
+
|
|
70
|
+
`manifest.json` example:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"spec": "session-bundle-v1",
|
|
75
|
+
"version": 1,
|
|
76
|
+
"source": "playwright-storage-state",
|
|
77
|
+
"cookie_count": 12,
|
|
78
|
+
"origin_count": 3,
|
|
79
|
+
"indexeddb_count": 0
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CLI
|
|
84
|
+
|
|
85
|
+
| Command | Description |
|
|
86
|
+
|---------|-------------|
|
|
87
|
+
| `session-bundle export --playwright-context FILE -o OUT.zip` | Create bundle from Playwright state |
|
|
88
|
+
| `session-bundle import FILE --dry-run` | Validate bundle without writing (default) |
|
|
89
|
+
| `session-bundle diff A.zip B.zip` | Cookie domain + storage/IDB diff |
|
|
90
|
+
| `session-bundle mlx-pull --profile-id UUID -o bundle.zip` | Export MLX profile cookies → bundle (`[mlx]`) |
|
|
91
|
+
| `session-bundle mlx-push --profile-id UUID --bundle FILE` | Import bundle cookies to MLX (`[mlx]`) |
|
|
92
|
+
| `session-bundle mlx-push ... --dry-run` | Validate bundle; no MLX API calls |
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from session_bundle_kit import export_playwright_context, validate_bundle, diff_bundles
|
|
98
|
+
|
|
99
|
+
export_playwright_context("state.json", "bundle.zip")
|
|
100
|
+
report = validate_bundle("bundle.zip")
|
|
101
|
+
diff = diff_bundles("old.zip", "new.zip")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Restore to Playwright:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from session_bundle_kit.bundle import SessionBundle
|
|
108
|
+
|
|
109
|
+
bundle = SessionBundle.read_zip("bundle.zip")
|
|
110
|
+
context = await browser.new_context(storage_state=bundle.to_playwright_storage_state())
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## MLX pull / push (`[mlx]` extra)
|
|
114
|
+
|
|
115
|
+
Round-trip **cookies** between MLX profiles and neutral **session-bundle-v1** zips. Storage/IDB in bundles from Playwright export are manifest-only on push; MLX Launcher APIs move cookies only.
|
|
116
|
+
|
|
117
|
+
**Pull** (profile → zip):
|
|
118
|
+
|
|
119
|
+
1. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
|
|
120
|
+
2. `POST launcher.mlx.yt:45001/api/v1/cookies/export`
|
|
121
|
+
|
|
122
|
+
**Push** (zip → profile):
|
|
123
|
+
|
|
124
|
+
1. Validate bundle (`--dry-run` stops here)
|
|
125
|
+
2. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
|
|
126
|
+
3. `POST launcher.mlx.yt:45001/api/v1/cookies/import`
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
export MLX_TOKEN="..."
|
|
130
|
+
|
|
131
|
+
# Export MLX profile session to portable bundle
|
|
132
|
+
session-bundle mlx-pull --profile-id PROFILE_UUID -o bundle.zip
|
|
133
|
+
|
|
134
|
+
# Validate before import
|
|
135
|
+
session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip --dry-run
|
|
136
|
+
|
|
137
|
+
# Import cookies into target profile
|
|
138
|
+
session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Peer pattern for Launcher lifecycle: see `cdp-connect-kit` MLX integration docs.
|
|
142
|
+
|
|
143
|
+
## When login sessions break after profile switch (playbook)
|
|
144
|
+
|
|
145
|
+
Sites re-challenge when cookies land on a **new fingerprint or IP**. Use bundles to move **stored** credentials deliberately — not as a bypass.
|
|
146
|
+
|
|
147
|
+
| Symptom | Likely cause | Next step |
|
|
148
|
+
|---------|--------------|-----------|
|
|
149
|
+
| Import ok, still logged out | Domain/subdomain mismatch, expired cookies | `session-bundle diff` old vs new; fix with [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) |
|
|
150
|
+
| Step-up / CAPTCHA after restore | IP or fingerprint drift | Match proxy lane; probe with [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) |
|
|
151
|
+
| MLX push succeeds, site fails | Cookies only — no `localStorage` on target | Restore storage via Playwright `storage_state` on same profile |
|
|
152
|
+
| Migration metadata only | `antidetect-importer` left `_cookies` sidecar | `mlx-pull` source → edit → `mlx-push --dry-run` → push |
|
|
153
|
+
|
|
154
|
+
**Session migration pipeline:**
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
session-bundle export --playwright-context state.json -o bundle.zip
|
|
158
|
+
session-bundle import bundle.zip --dry-run
|
|
159
|
+
session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip --dry-run
|
|
160
|
+
export MLX_TOKEN=...
|
|
161
|
+
session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip
|
|
162
|
+
cdp-probe mlx --profile-id TARGET_UUID --url https://your-app.example # verify session + exposure
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Treat bundle zips as **secrets** — same sensitivity as password files.
|
|
166
|
+
|
|
167
|
+
## When Chrome `user-data-dir` fails in 2026
|
|
168
|
+
|
|
169
|
+
Starting with **Chrome 136** (March 2025), Google changed how remote debugging works on the default profile. Per the [Chrome Developers blog](https://developer.chrome.com/blog/remote-debugging-port):
|
|
170
|
+
|
|
171
|
+
- `--remote-debugging-port` and `--remote-debugging-pipe` are **ignored** when targeting Chrome's **default** user data directory.
|
|
172
|
+
- You must pass a **custom** `--user-data-dir` pointing to a non-default profile path for CDP to bind.
|
|
173
|
+
- The change targets cookie theft via remote debugging after [App-Bound Encryption](https://developer.chrome.com/blog/app-bound-encryption); Chrome for Testing still supports the older automation workflow.
|
|
174
|
+
|
|
175
|
+
**Practical impact:** copying your daily `Default` profile and launching with `--remote-debugging-port` no longer works on stock Chrome 136+. Session-bundle-kit sidesteps this by exporting **Playwright `storage_state.json`** (cookies + origin storage) into portable zips — restore via `new_context(storage_state=...)` on antidetect or isolated profiles instead of attaching CDP to your real Chrome profile.
|
|
176
|
+
|
|
177
|
+
Enterprise admins can still control remote debugging via the [Allow remote debugging](https://support.google.com/chrome/a/answer/2657289) Chrome policy on managed devices.
|
|
178
|
+
|
|
179
|
+
## Limitations
|
|
180
|
+
|
|
181
|
+
- **No live IDB export** — IndexedDB section is metadata manifest only.
|
|
182
|
+
- **sessionStorage** preserved in bundle format but Playwright native export may omit it; include in custom state JSON if needed.
|
|
183
|
+
- **mlx-push** imports cookies only; storage must be restored via Playwright or profile sync separately.
|
|
184
|
+
- **Secrets** — bundles contain session secrets; treat zip files as credentials. Import warns on likely plaintext passwords in web storage.
|
|
185
|
+
|
|
186
|
+
## Production
|
|
187
|
+
|
|
188
|
+
Export sessions to portable zips, validate with `mlx-push --dry-run`, then import cookies into MLX profiles after `antidetect-importer` migration or failed login on a new profile.
|
|
189
|
+
|
|
190
|
+
**Partner note (affiliate):** When restoring sessions into **isolated Multilogin X** profiles (not shared Chrome `user-data-dir`), Launcher cookie import pairs with profile-level proxy and fingerprint. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Export/diff/validate work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `session-bundle --show-deal` (never printed by default).
|
|
191
|
+
|
|
192
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright storage_state export, Chrome 136 CDP, MLX cookie import.
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
## Related tools (on PyPI)
|
|
196
|
+
|
|
197
|
+
| Package | CLI | Role |
|
|
198
|
+
|---------|-----|------|
|
|
199
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
200
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
201
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
202
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
203
|
+
|
|
204
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
MIT
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
213
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|