Files
human_mouse/README.md
Huang Qi 65ef838bd7 feat: initial release of human_mouse v0.1.0
A small Python library for replaying real human mouse trajectories from
the SapiMouse dataset onto a Playwright page. Designed for ML-based
bot-detection research, behavioral biometrics prototyping, and
replay-based test fixtures.

Public API: load_all_segments, pick_segments, affine_warp, upsample,
replay, replay_random, download_sapimouse.

- src/ layout with hatchling build backend
- 23 pytest tests (10 transform unit + 13 integration)
- MIT license, PEP 561 py.typed marker
- python -m human_mouse download for one-shot dataset fetch
- examples/cloakbrowser_demo.py demonstrates end-to-end use with CloakBrowser

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 00:30:18 +08:00

3.9 KiB

human_mouse

Replay real human mouse trajectories from the SapiMouse 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

uv add human_mouse              # or: pip install human_mouse
uv add "human_mouse[demo]"      # also installs cloakbrowser for the example

One-time dataset download

import human_mouse as hm
hm.download_sapimouse("./data")   # ~8 MB, no registration

This unzips SapiMouse to ./data/sapimouse/userN/....

Quick start

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:

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:

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.