human-input-kit 0.2.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.
- human_input_kit-0.2.1/.github/workflows/ci.yml +31 -0
- human_input_kit-0.2.1/.github/workflows/release.yml +54 -0
- human_input_kit-0.2.1/.gitignore +12 -0
- human_input_kit-0.2.1/CHANGELOG.md +37 -0
- human_input_kit-0.2.1/LICENSE +21 -0
- human_input_kit-0.2.1/PKG-INFO +272 -0
- human_input_kit-0.2.1/README.md +238 -0
- human_input_kit-0.2.1/docs/AFFILIATE.md +58 -0
- human_input_kit-0.2.1/docs/FAQ.md +37 -0
- human_input_kit-0.2.1/docs/assets/.gitkeep +0 -0
- human_input_kit-0.2.1/examples/demo_warmup.py +51 -0
- human_input_kit-0.2.1/examples/mlx_warmup_demo.py +200 -0
- human_input_kit-0.2.1/human_input_kit/__init__.py +23 -0
- human_input_kit-0.2.1/human_input_kit/async_.py +19 -0
- human_input_kit-0.2.1/human_input_kit/bezier.py +68 -0
- human_input_kit-0.2.1/human_input_kit/cli.py +100 -0
- human_input_kit-0.2.1/human_input_kit/deal.py +25 -0
- human_input_kit-0.2.1/human_input_kit/gesture_schema.py +90 -0
- human_input_kit-0.2.1/human_input_kit/gestures.py +84 -0
- human_input_kit-0.2.1/human_input_kit/idle.py +41 -0
- human_input_kit-0.2.1/human_input_kit/keyboard.py +31 -0
- human_input_kit-0.2.1/human_input_kit/record.py +90 -0
- human_input_kit-0.2.1/human_input_kit/replay.py +57 -0
- human_input_kit-0.2.1/human_input_kit/rng.py +16 -0
- human_input_kit-0.2.1/human_input_kit/scroll.py +28 -0
- human_input_kit-0.2.1/human_input_kit/sync_.py +143 -0
- human_input_kit-0.2.1/pyproject.toml +86 -0
- human_input_kit-0.2.1/recipes/scroll_news.py +63 -0
- human_input_kit-0.2.1/recipes/youtube_idle.py +69 -0
- human_input_kit-0.2.1/tests/conftest.py +9 -0
- human_input_kit-0.2.1/tests/test_async_module.py +16 -0
- human_input_kit-0.2.1/tests/test_benchmark_bezier.py +16 -0
- human_input_kit-0.2.1/tests/test_bezier.py +20 -0
- human_input_kit-0.2.1/tests/test_cli.py +62 -0
- human_input_kit-0.2.1/tests/test_gesture_schema.py +47 -0
- human_input_kit-0.2.1/tests/test_gestures.py +23 -0
- human_input_kit-0.2.1/tests/test_mlx_warmup_demo.py +52 -0
- human_input_kit-0.2.1/tests/test_playwright_actions.py +41 -0
- human_input_kit-0.2.1/tests/test_record.py +16 -0
- human_input_kit-0.2.1/tests/test_replay.py +28 -0
- human_input_kit-0.2.1/tests/test_sync_api.py +27 -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,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.2.1 — 2026-06-11
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- PyPI README: SEO subtitle, warmup playbook (cadence vs fingerprint), contextual affiliate note
|
|
8
|
+
- Fixed Install code fence typo in README
|
|
9
|
+
- `pyproject.toml`: search keywords (`human-like-mouse`, `playwright-warmup`, `bot-detection`)
|
|
10
|
+
- `--show-deal`: contextual folder-scale warmup copy with affiliate disclosure
|
|
11
|
+
- FAQ: +4 SEO questions (human scroll, warmup script, N-profile MLX, affiliate opt-in)
|
|
12
|
+
|
|
13
|
+
## v0.2.0 — 2026-06-11
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `examples/mlx_warmup_demo.py` — MLX Launcher warmup pseudocode with TODO markers; cdp-connect-kit peer pattern
|
|
18
|
+
- README: MLX single-profile warmup vs production N-profile warmup via automation-farm-runner
|
|
19
|
+
- Optional `[mlx]` extra marker (no added dependencies)
|
|
20
|
+
|
|
21
|
+
- Deterministic mode: global `--seed 42` on CLI (default 42) for reproducible demos/tests
|
|
22
|
+
- `human_input_kit.sync_` — Playwright **sync** API (`move_mouse_along`, `human_type`, etc.)
|
|
23
|
+
- `human_input_kit.async_` — Playwright **async** API module (re-exports async helpers)
|
|
24
|
+
- Gesture JSON schema validation before `replay` (CLI fails fast with clear errors)
|
|
25
|
+
- `examples/demo_warmup.py` with `--seed`, `--url`, `--headed` CLI args
|
|
26
|
+
- Bezier benchmark test (100 points, loose <50ms CI ceiling; target <10ms)
|
|
27
|
+
- README demo GIF placeholder path `docs/assets/demo.gif`
|
|
28
|
+
- GitHub Actions CI (Python 3.10–3.12)
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Top-level `human_input_kit` exports sync Playwright helpers by default
|
|
33
|
+
- `load_recording(..., validate=True)` validates schema before parsing
|
|
34
|
+
|
|
35
|
+
## v0.1.0 — 2026-06-01
|
|
36
|
+
|
|
37
|
+
- Initial release: Bezier paths, scroll/typing/idle helpers, record/replay CLI
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 human-input-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,272 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: human-input-kit
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Human-like Playwright mouse, scroll, and typing — Bezier warmup with deterministic seeds. CLI: human-input.
|
|
5
|
+
Project-URL: Homepage, https://github.com/human-input-kit/human-input-kit
|
|
6
|
+
Project-URL: Documentation, https://github.com/human-input-kit/human-input-kit#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/human-input-kit/human-input-kit
|
|
8
|
+
Project-URL: Issues, https://github.com/human-input-kit/human-input-kit/issues
|
|
9
|
+
Author: human-input-kit contributors
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: behavior-replay,bezier-curve,bot-cadence,bot-detection,gesture-recording,human-behavior,human-like-mouse,idle-jitter,interaction-polish,mouse-movement,multilogin-warmup,playwright-input,playwright-scroll,playwright-warmup,scroll-simulation,typing-simulation,warmup-script
|
|
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: pytest-asyncio>=0.24; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
32
|
+
Provides-Extra: mlx
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# human-input-kit
|
|
36
|
+
|
|
37
|
+
**Human-like Playwright mouse & scroll** — Bezier paths, typing delays, and warmup recipes with deterministic seeds.
|
|
38
|
+
|
|
39
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
40
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
41
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install human-input-kit
|
|
45
|
+
human-input --help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
CLI: **`human-input`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
49
|
+
|
|
50
|
+
Human-like **mouse**, **scroll**, and **typing** helpers for Playwright — Bezier paths, variable delays, idle jitter, and gesture record/replay.
|
|
51
|
+
|
|
52
|
+
## Problem
|
|
53
|
+
|
|
54
|
+
Raw `page.click()` and `page.keyboard.type()` bursts look mechanical. Warmup workflows need curved mouse paths, uneven scroll cadence, and typing pauses. Teams reinvent these snippets in every scraper.
|
|
55
|
+
|
|
56
|
+
`human-input-kit` packages the primitives and a small CLI for demo, record, and replay flows.
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install human-input-kit
|
|
62
|
+
playwright install chromium
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Development:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install human-input-kit[dev]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
> Placeholder: add a screen recording at `docs/assets/demo.gif` (not shipped in the wheel).
|
|
74
|
+
|
|
75
|
+
## Quick start
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Reproducible motion (default seed 42)
|
|
79
|
+
human-input --seed 42 demo-scroll --url https://news.ycombinator.com
|
|
80
|
+
human-input record --duration 30 -o gestures.json
|
|
81
|
+
human-input replay gestures.json # validates gesture JSON schema first
|
|
82
|
+
|
|
83
|
+
# Runnable warmup example
|
|
84
|
+
python examples/demo_warmup.py --seed 42
|
|
85
|
+
|
|
86
|
+
# Documented recipes (deterministic with --seed)
|
|
87
|
+
python recipes/scroll_news.py --seed 42
|
|
88
|
+
python recipes/youtube_idle.py --seed 42 --seconds 30 --headed
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Sync Playwright API** (default package exports):
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from human_input_kit import (
|
|
95
|
+
bezier_mouse_path,
|
|
96
|
+
human_type,
|
|
97
|
+
idle_jitter,
|
|
98
|
+
move_mouse_along,
|
|
99
|
+
random_scroll,
|
|
100
|
+
seed_rng,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
seed_rng(42)
|
|
104
|
+
path = bezier_mouse_path((100, 100), (500, 300))
|
|
105
|
+
move_mouse_along(page, path) # sync Page
|
|
106
|
+
random_scroll(page, bursts=4)
|
|
107
|
+
idle_jitter(page)
|
|
108
|
+
human_type(page, "input[name='q']", "playwright warmup")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Async Playwright API** (`human_input_kit.async_`):
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from human_input_kit import seed_rng
|
|
115
|
+
from human_input_kit import async_ as human_async
|
|
116
|
+
|
|
117
|
+
seed_rng(42)
|
|
118
|
+
path = human_async.bezier_mouse_path((100, 100), (500, 300))
|
|
119
|
+
await human_async.move_mouse_along(page, path)
|
|
120
|
+
await human_async.random_scroll(page, bursts=4)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
See `examples/demo_warmup.py` for a full async script.
|
|
124
|
+
|
|
125
|
+
### Recipes
|
|
126
|
+
|
|
127
|
+
Copy-paste scripts in [`recipes/`](recipes/) for common warmup patterns. Each accepts `--seed` so demo motion is reproducible in CI and screen recordings.
|
|
128
|
+
|
|
129
|
+
| Recipe | Command | Behavior |
|
|
130
|
+
|--------|---------|----------|
|
|
131
|
+
| News scroll | `python recipes/scroll_news.py --seed 42` | Bezier drift → scroll bursts → idle jitter on a news feed |
|
|
132
|
+
| YouTube idle | `python recipes/youtube_idle.py --seed 42 --headed` | Idle micro-moves + rare scroll on `youtube.com` |
|
|
133
|
+
|
|
134
|
+
Options: `--url`, `--headed` (both); `--bursts` (scroll_news); `--seconds` (youtube_idle).
|
|
135
|
+
|
|
136
|
+
## MLX warmup (single profile)
|
|
137
|
+
|
|
138
|
+
`human-input-kit` does **not** bundle MLX or Launcher clients. For one-off MLX profile warmup, follow the **cdp-connect-kit** peer pattern:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pip install human-input-kit
|
|
142
|
+
pip install cdp-connect-kit[mlx] # peer dependency — not required by human-input-kit
|
|
143
|
+
playwright install chromium
|
|
144
|
+
|
|
145
|
+
export MLX_TOKEN=your_bearer_token
|
|
146
|
+
export MLX_FOLDER_ID=your-folder-uuid
|
|
147
|
+
|
|
148
|
+
# Pseudocode demo with TODO markers for Launcher start/stop:
|
|
149
|
+
python examples/mlx_warmup_demo.py --profile-id PROFILE_UUID
|
|
150
|
+
|
|
151
|
+
# Or warmup an already-started profile (CDP_URL from Launcher):
|
|
152
|
+
CDP_URL=http://127.0.0.1:55513 python examples/mlx_warmup_demo.py --profile-id PROFILE_UUID
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`examples/mlx_warmup_demo.py` documents: Launcher start → `connect_over_cdp` → Bezier scroll/jitter warmup → Launcher stop. Set `HUMAN_INPUT_KIT_MLX_DEMO=1` after installing `cdp-connect-kit[mlx]` to enable the live Launcher calls.
|
|
156
|
+
|
|
157
|
+
Optional marker extra (installs nothing): `pip install human-input-kit[mlx]`
|
|
158
|
+
|
|
159
|
+
## CLI
|
|
160
|
+
|
|
161
|
+
| Command | Description |
|
|
162
|
+
|---------|-------------|
|
|
163
|
+
| `human-input demo-scroll --url URL` | Scroll + idle jitter demo |
|
|
164
|
+
| `human-input record --duration SEC -o FILE` | Record gestures JSON |
|
|
165
|
+
| `human-input replay FILE` | Replay saved gestures (schema-validated) |
|
|
166
|
+
| `human-input --seed N` | Global RNG seed on all subcommands (default `42`) |
|
|
167
|
+
|
|
168
|
+
## API
|
|
169
|
+
|
|
170
|
+
| Module | Use with |
|
|
171
|
+
|--------|----------|
|
|
172
|
+
| `human_input_kit` | Playwright **sync** `Page` |
|
|
173
|
+
| `human_input_kit.async_` | Playwright **async** `Page` |
|
|
174
|
+
| `human_input_kit.bezier` | Path math only (`bezier_mouse_path`) |
|
|
175
|
+
|
|
176
|
+
| Function | Description |
|
|
177
|
+
|----------|-------------|
|
|
178
|
+
| `bezier_mouse_path(start, end, steps=25)` | Cubic Bezier point list (sync, fast) |
|
|
179
|
+
| `move_mouse_along(page, path)` | Animate mouse along path |
|
|
180
|
+
| `human_type(page, selector, text)` | Variable per-char typing delays |
|
|
181
|
+
| `random_scroll(page, bursts=3)` | Random wheel bursts with pauses |
|
|
182
|
+
| `idle_jitter(page, moves=4)` | Small idle hand movements |
|
|
183
|
+
| `seed_rng(n)` | Deterministic variance for tests/demos |
|
|
184
|
+
| `load_recording(path, validate=True)` | Load gestures JSON with schema check |
|
|
185
|
+
|
|
186
|
+
### Gesture format
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"version": 1,
|
|
191
|
+
"url": "https://news.ycombinator.com",
|
|
192
|
+
"events": [
|
|
193
|
+
{"type": "move", "t": 0.0, "x": 120, "y": 80},
|
|
194
|
+
{"type": "scroll", "t": 1.2, "dy": 320}
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Behavioral mimicry vs profile isolation
|
|
200
|
+
|
|
201
|
+
Human-like mouse paths and scroll timing can reduce **obvious automation cadence**, but behavioral mimicry alone is **necessary and insufficient** for production multi-account workflows.
|
|
202
|
+
|
|
203
|
+
Detection stacks also correlate:
|
|
204
|
+
|
|
205
|
+
- Browser fingerprint consistency (UA, WebGL, Client Hints)
|
|
206
|
+
- IP / proxy reputation
|
|
207
|
+
- Cookie and storage isolation
|
|
208
|
+
- TLS and network signals
|
|
209
|
+
|
|
210
|
+
Use `human-input-kit` for **warmup and interaction polish** inside an already-isolated profile (dedicated browser profile, proxy, and storage boundary). Pair with [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) and [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) for profile-level QA.
|
|
211
|
+
|
|
212
|
+
## When mechanical clicks still get flagged (playbook)
|
|
213
|
+
|
|
214
|
+
Behavior polish helps **cadence** — not fingerprint or IP. Typical order of operations:
|
|
215
|
+
|
|
216
|
+
| Signal still failing | Tool | Action |
|
|
217
|
+
|----------------------|------|--------|
|
|
218
|
+
| Teleport mouse / constant intervals | `human-input-kit` | Bezier paths, `--seed` for reproducible demos |
|
|
219
|
+
| UA / screen / timezone mismatch | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | Audit profile before warmup |
|
|
220
|
+
| `navigator.webdriver` / headless leaks | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | Compare vanilla vs Launcher CDP |
|
|
221
|
+
| One profile ok, N profiles not | `automation-farm-runner` | `farm-runner mlx-pool` + warmup script reading `CDP_URL` |
|
|
222
|
+
|
|
223
|
+
**Warmup pipeline (single profile):**
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
export MLX_TOKEN=... MLX_FOLDER_ID=...
|
|
227
|
+
# cdp-connect-kit starts profile → CDP_URL
|
|
228
|
+
CDP_URL=http://127.0.0.1:PORT python examples/mlx_warmup_demo.py --profile-id UUID
|
|
229
|
+
human-input --seed 42 demo-scroll --url https://news.ycombinator.com
|
|
230
|
+
cdp-probe mlx --profile-id UUID --url https://example.com
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Warmup at scale:** farm job imports `human_input_kit`, reads `CDP_URL` / `PROFILE_ID` from env — gestures stay in this package; queueing stays in `farm-runner`.
|
|
234
|
+
|
|
235
|
+
## Limitations
|
|
236
|
+
|
|
237
|
+
- **Playwright only** — APIs expect a Playwright `Page`.
|
|
238
|
+
- **Record mode** captures DOM events + scripted warmup; not a full OS-level input recorder.
|
|
239
|
+
- **Not undetectable** — reduces mechanical patterns; does not spoof fingerprints or network identity.
|
|
240
|
+
- **Headless motion** — some sites behave differently in headless Chromium.
|
|
241
|
+
|
|
242
|
+
## Production
|
|
243
|
+
|
|
244
|
+
For **many profiles** (folder pool, cron, concurrency), use **`farm-runner`** (`automation-farm-runner`) with a warmup script that imports `human_input_kit` and reads `CDP_URL` / `PROFILE_ID`. This package is the gesture library; the farm runner owns MLX pool lifecycle.
|
|
245
|
+
|
|
246
|
+
**Partner note (affiliate):** Human-like input pays off **inside** isolated Multilogin X profiles (proxy + fingerprint already matched) — not on leaky vanilla Chromium. If folder-scale warmup is your bottleneck, eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Demos and recipes work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `human-input --show-deal` (never printed by default).
|
|
247
|
+
|
|
248
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — human-like mouse movement, Playwright scroll warmup, bot detection cadence.
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
## Related tools (on PyPI)
|
|
255
|
+
|
|
256
|
+
| Package | CLI | Role |
|
|
257
|
+
|---------|-----|------|
|
|
258
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
259
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
260
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
261
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
262
|
+
|
|
263
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
272
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# human-input-kit
|
|
2
|
+
|
|
3
|
+
**Human-like Playwright mouse & scroll** — Bezier paths, typing delays, and warmup recipes with deterministic seeds.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
6
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
7
|
+
[](https://pypi.org/project/human-input-kit/)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install human-input-kit
|
|
11
|
+
human-input --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
CLI: **`human-input`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
|
|
15
|
+
|
|
16
|
+
Human-like **mouse**, **scroll**, and **typing** helpers for Playwright — Bezier paths, variable delays, idle jitter, and gesture record/replay.
|
|
17
|
+
|
|
18
|
+
## Problem
|
|
19
|
+
|
|
20
|
+
Raw `page.click()` and `page.keyboard.type()` bursts look mechanical. Warmup workflows need curved mouse paths, uneven scroll cadence, and typing pauses. Teams reinvent these snippets in every scraper.
|
|
21
|
+
|
|
22
|
+
`human-input-kit` packages the primitives and a small CLI for demo, record, and replay flows.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install human-input-kit
|
|
28
|
+
playwright install chromium
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Development:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install human-input-kit[dev]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
> Placeholder: add a screen recording at `docs/assets/demo.gif` (not shipped in the wheel).
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Reproducible motion (default seed 42)
|
|
45
|
+
human-input --seed 42 demo-scroll --url https://news.ycombinator.com
|
|
46
|
+
human-input record --duration 30 -o gestures.json
|
|
47
|
+
human-input replay gestures.json # validates gesture JSON schema first
|
|
48
|
+
|
|
49
|
+
# Runnable warmup example
|
|
50
|
+
python examples/demo_warmup.py --seed 42
|
|
51
|
+
|
|
52
|
+
# Documented recipes (deterministic with --seed)
|
|
53
|
+
python recipes/scroll_news.py --seed 42
|
|
54
|
+
python recipes/youtube_idle.py --seed 42 --seconds 30 --headed
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Sync Playwright API** (default package exports):
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from human_input_kit import (
|
|
61
|
+
bezier_mouse_path,
|
|
62
|
+
human_type,
|
|
63
|
+
idle_jitter,
|
|
64
|
+
move_mouse_along,
|
|
65
|
+
random_scroll,
|
|
66
|
+
seed_rng,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
seed_rng(42)
|
|
70
|
+
path = bezier_mouse_path((100, 100), (500, 300))
|
|
71
|
+
move_mouse_along(page, path) # sync Page
|
|
72
|
+
random_scroll(page, bursts=4)
|
|
73
|
+
idle_jitter(page)
|
|
74
|
+
human_type(page, "input[name='q']", "playwright warmup")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Async Playwright API** (`human_input_kit.async_`):
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from human_input_kit import seed_rng
|
|
81
|
+
from human_input_kit import async_ as human_async
|
|
82
|
+
|
|
83
|
+
seed_rng(42)
|
|
84
|
+
path = human_async.bezier_mouse_path((100, 100), (500, 300))
|
|
85
|
+
await human_async.move_mouse_along(page, path)
|
|
86
|
+
await human_async.random_scroll(page, bursts=4)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
See `examples/demo_warmup.py` for a full async script.
|
|
90
|
+
|
|
91
|
+
### Recipes
|
|
92
|
+
|
|
93
|
+
Copy-paste scripts in [`recipes/`](recipes/) for common warmup patterns. Each accepts `--seed` so demo motion is reproducible in CI and screen recordings.
|
|
94
|
+
|
|
95
|
+
| Recipe | Command | Behavior |
|
|
96
|
+
|--------|---------|----------|
|
|
97
|
+
| News scroll | `python recipes/scroll_news.py --seed 42` | Bezier drift → scroll bursts → idle jitter on a news feed |
|
|
98
|
+
| YouTube idle | `python recipes/youtube_idle.py --seed 42 --headed` | Idle micro-moves + rare scroll on `youtube.com` |
|
|
99
|
+
|
|
100
|
+
Options: `--url`, `--headed` (both); `--bursts` (scroll_news); `--seconds` (youtube_idle).
|
|
101
|
+
|
|
102
|
+
## MLX warmup (single profile)
|
|
103
|
+
|
|
104
|
+
`human-input-kit` does **not** bundle MLX or Launcher clients. For one-off MLX profile warmup, follow the **cdp-connect-kit** peer pattern:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install human-input-kit
|
|
108
|
+
pip install cdp-connect-kit[mlx] # peer dependency — not required by human-input-kit
|
|
109
|
+
playwright install chromium
|
|
110
|
+
|
|
111
|
+
export MLX_TOKEN=your_bearer_token
|
|
112
|
+
export MLX_FOLDER_ID=your-folder-uuid
|
|
113
|
+
|
|
114
|
+
# Pseudocode demo with TODO markers for Launcher start/stop:
|
|
115
|
+
python examples/mlx_warmup_demo.py --profile-id PROFILE_UUID
|
|
116
|
+
|
|
117
|
+
# Or warmup an already-started profile (CDP_URL from Launcher):
|
|
118
|
+
CDP_URL=http://127.0.0.1:55513 python examples/mlx_warmup_demo.py --profile-id PROFILE_UUID
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`examples/mlx_warmup_demo.py` documents: Launcher start → `connect_over_cdp` → Bezier scroll/jitter warmup → Launcher stop. Set `HUMAN_INPUT_KIT_MLX_DEMO=1` after installing `cdp-connect-kit[mlx]` to enable the live Launcher calls.
|
|
122
|
+
|
|
123
|
+
Optional marker extra (installs nothing): `pip install human-input-kit[mlx]`
|
|
124
|
+
|
|
125
|
+
## CLI
|
|
126
|
+
|
|
127
|
+
| Command | Description |
|
|
128
|
+
|---------|-------------|
|
|
129
|
+
| `human-input demo-scroll --url URL` | Scroll + idle jitter demo |
|
|
130
|
+
| `human-input record --duration SEC -o FILE` | Record gestures JSON |
|
|
131
|
+
| `human-input replay FILE` | Replay saved gestures (schema-validated) |
|
|
132
|
+
| `human-input --seed N` | Global RNG seed on all subcommands (default `42`) |
|
|
133
|
+
|
|
134
|
+
## API
|
|
135
|
+
|
|
136
|
+
| Module | Use with |
|
|
137
|
+
|--------|----------|
|
|
138
|
+
| `human_input_kit` | Playwright **sync** `Page` |
|
|
139
|
+
| `human_input_kit.async_` | Playwright **async** `Page` |
|
|
140
|
+
| `human_input_kit.bezier` | Path math only (`bezier_mouse_path`) |
|
|
141
|
+
|
|
142
|
+
| Function | Description |
|
|
143
|
+
|----------|-------------|
|
|
144
|
+
| `bezier_mouse_path(start, end, steps=25)` | Cubic Bezier point list (sync, fast) |
|
|
145
|
+
| `move_mouse_along(page, path)` | Animate mouse along path |
|
|
146
|
+
| `human_type(page, selector, text)` | Variable per-char typing delays |
|
|
147
|
+
| `random_scroll(page, bursts=3)` | Random wheel bursts with pauses |
|
|
148
|
+
| `idle_jitter(page, moves=4)` | Small idle hand movements |
|
|
149
|
+
| `seed_rng(n)` | Deterministic variance for tests/demos |
|
|
150
|
+
| `load_recording(path, validate=True)` | Load gestures JSON with schema check |
|
|
151
|
+
|
|
152
|
+
### Gesture format
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"version": 1,
|
|
157
|
+
"url": "https://news.ycombinator.com",
|
|
158
|
+
"events": [
|
|
159
|
+
{"type": "move", "t": 0.0, "x": 120, "y": 80},
|
|
160
|
+
{"type": "scroll", "t": 1.2, "dy": 320}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Behavioral mimicry vs profile isolation
|
|
166
|
+
|
|
167
|
+
Human-like mouse paths and scroll timing can reduce **obvious automation cadence**, but behavioral mimicry alone is **necessary and insufficient** for production multi-account workflows.
|
|
168
|
+
|
|
169
|
+
Detection stacks also correlate:
|
|
170
|
+
|
|
171
|
+
- Browser fingerprint consistency (UA, WebGL, Client Hints)
|
|
172
|
+
- IP / proxy reputation
|
|
173
|
+
- Cookie and storage isolation
|
|
174
|
+
- TLS and network signals
|
|
175
|
+
|
|
176
|
+
Use `human-input-kit` for **warmup and interaction polish** inside an already-isolated profile (dedicated browser profile, proxy, and storage boundary). Pair with [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) and [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) for profile-level QA.
|
|
177
|
+
|
|
178
|
+
## When mechanical clicks still get flagged (playbook)
|
|
179
|
+
|
|
180
|
+
Behavior polish helps **cadence** — not fingerprint or IP. Typical order of operations:
|
|
181
|
+
|
|
182
|
+
| Signal still failing | Tool | Action |
|
|
183
|
+
|----------------------|------|--------|
|
|
184
|
+
| Teleport mouse / constant intervals | `human-input-kit` | Bezier paths, `--seed` for reproducible demos |
|
|
185
|
+
| UA / screen / timezone mismatch | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | Audit profile before warmup |
|
|
186
|
+
| `navigator.webdriver` / headless leaks | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | Compare vanilla vs Launcher CDP |
|
|
187
|
+
| One profile ok, N profiles not | `automation-farm-runner` | `farm-runner mlx-pool` + warmup script reading `CDP_URL` |
|
|
188
|
+
|
|
189
|
+
**Warmup pipeline (single profile):**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
export MLX_TOKEN=... MLX_FOLDER_ID=...
|
|
193
|
+
# cdp-connect-kit starts profile → CDP_URL
|
|
194
|
+
CDP_URL=http://127.0.0.1:PORT python examples/mlx_warmup_demo.py --profile-id UUID
|
|
195
|
+
human-input --seed 42 demo-scroll --url https://news.ycombinator.com
|
|
196
|
+
cdp-probe mlx --profile-id UUID --url https://example.com
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Warmup at scale:** farm job imports `human_input_kit`, reads `CDP_URL` / `PROFILE_ID` from env — gestures stay in this package; queueing stays in `farm-runner`.
|
|
200
|
+
|
|
201
|
+
## Limitations
|
|
202
|
+
|
|
203
|
+
- **Playwright only** — APIs expect a Playwright `Page`.
|
|
204
|
+
- **Record mode** captures DOM events + scripted warmup; not a full OS-level input recorder.
|
|
205
|
+
- **Not undetectable** — reduces mechanical patterns; does not spoof fingerprints or network identity.
|
|
206
|
+
- **Headless motion** — some sites behave differently in headless Chromium.
|
|
207
|
+
|
|
208
|
+
## Production
|
|
209
|
+
|
|
210
|
+
For **many profiles** (folder pool, cron, concurrency), use **`farm-runner`** (`automation-farm-runner`) with a warmup script that imports `human_input_kit` and reads `CDP_URL` / `PROFILE_ID`. This package is the gesture library; the farm runner owns MLX pool lifecycle.
|
|
211
|
+
|
|
212
|
+
**Partner note (affiliate):** Human-like input pays off **inside** isolated Multilogin X profiles (proxy + fingerprint already matched) — not on leaky vanilla Chromium. If folder-scale warmup is your bottleneck, eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Demos and recipes work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `human-input --show-deal` (never printed by default).
|
|
213
|
+
|
|
214
|
+
**FAQ:** [docs/FAQ.md](docs/FAQ.md) — human-like mouse movement, Playwright scroll warmup, bot detection cadence.
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
## Related tools (on PyPI)
|
|
221
|
+
|
|
222
|
+
| Package | CLI | Role |
|
|
223
|
+
|---------|-----|------|
|
|
224
|
+
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
|
|
225
|
+
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
|
|
226
|
+
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
|
|
227
|
+
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
|
|
228
|
+
|
|
229
|
+
**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
**Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
|
|
238
|
+
More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
|