# human_mouse Replay real human mouse trajectories from the [SapiMouse](https://www.ms.sapientia.ro/~manyi/sapimouse/sapimouse.html) dataset onto a Playwright page. Useful when you need mouse movement that is statistically indistinguishable from a real user — for ML-based bot-detection research, behavioral biometrics prototyping, or replay-based test fixtures. ## Install ```bash uv add human_mouse # or: pip install human_mouse uv add "human_mouse[demo]" # also installs cloakbrowser for the example ``` ## One-time dataset download ```python import human_mouse as hm hm.download_sapimouse("./data") # ~8 MB, no registration ``` This unzips SapiMouse to `./data/sapimouse/userN/...`. ## Quick start ```python import human_mouse as hm from playwright.sync_api import sync_playwright with sync_playwright() as pw: browser = pw.chromium.launch(headless=False) page = browser.new_page() page.goto("https://example.com") # one-shot: pick a real human trajectory matching the distance and replay it seg = hm.replay_random( page, start=(100, 100), end=(900, 500), data_root="./data/sapimouse", density=4, # 4x spatial upsample for smoother visuals seed=42, ) print(f"replayed {seg.user}/{seg.session}, {len(seg.points)} source points") ``` ## Step-by-step API For full control over which segment is picked and how it's processed: ```python import human_mouse as hm segs = hm.load_all_segments("./data/sapimouse") seg = hm.pick_segments( segs, n=1, target_distance=1000, # only match segments ~1000 px long distance_tolerance=0.3, # ±30 % max_path_ratio=2.0, # skip erratic meanderers seed=42, )[0] points = hm.affine_warp(seg, (100, 100), (900, 500)) points = hm.upsample(points, factor=4) hm.replay(page, points, speed=1.0) ``` ## Public API | Symbol | Purpose | |---|---| | `Segment` | dataclass with `.points`, `.start`, `.end`, `.straight_distance`, `.path_length`, `.path_ratio`, `.duration_ms` | | `load_all_segments(data_root)` | scan SapiMouse, return every continuous Move-only segment ≥ 50 pts | | `pick_segments(segments, n, ...)` | filter by distance / path-ratio / distinct-session, randomly choose `n` | | `affine_warp(seg, start, end)` | translate + rotate + uniform-scale onto new endpoints (shape preserved) | | `upsample(points, factor)` | linearly interpolate `factor-1` sub-points between every adjacent pair | | `replay(page, points, speed=1.0)` | drive `page.mouse.move(...)` honoring the recorded `dt` | | `replay_random(page, start, end, data_root, ...)` | one-shot: pick + warp + upsample + replay | | `download_sapimouse(dest)` | download and unzip the dataset | ## Running the bundled example The `examples/` folder ships a Playwright canvas page (`demo.html`) plus a runner script that uses [CloakBrowser](https://github.com/CloakHQ/CloakBrowser): ```bash uv add "human_mouse[demo]" python -m human_mouse download ./sapimouse_data # one-time, ~8 MB uv run python examples/cloakbrowser_demo.py sapi # one trajectory uv run python examples/cloakbrowser_demo.py multi --n 10 # 10 overlaid ``` Outputs land in `./outputs/`: - `sapi.png` + `sapi.json` — single trajectory screenshot and per-event coords - `multi/overlay.png` + per-run JSONs + `summary.json` ## What `replay` is and isn't **Is**: a deterministic replay of one real human's mouse path, warped to your endpoints. The shape (curvature, hesitation, end-point fumbling) and the timing (`dt` distribution) come straight from a real recording. **Isn't**: a generator. It samples from a fixed dataset of ~4 000 segments. For per-call novelty, randomize the seed; for true synthesis, look at trajectory generative models (e.g. SapiAgent, DMTG). ## Dataset attribution If you use SapiMouse data in published work, cite: > Antal, M. et al. *SapiMouse: Mouse Dynamics-based User Authentication Using > Deep Feature Learning*. IEEE SACI 2021. ## License MIT.