botonomus.human¶
Human-like pointer, keyboard and wheel input.
botonomus.human
¶
Human-like pointer, keyboard and wheel input.
Human drives one page; HumanPage wraps a page so its click,
fill, type, press, hover and scroll (and locator equivalents) are
humanized automatically. HumanConfig holds the behaviour parameters, with
presets default, careful and fast.
HumanProfile
module-attribute
¶
HumanProfile = HumanConfig
Deprecated alias of HumanConfig, kept for 0.1 code; use HumanConfig.
Actionable
¶
NotActionableError
¶
Bases: BotonomusError, ValueError
An element did not become visible, enabled and stable in time.
Subclasses ValueError because 0.1 raised ValueError for an element
without a visible box.
Clock
¶
RealClock
¶
HumanConfig
dataclass
¶
HumanConfig(move_speed: float = 1.0, key_delay: float = 0.11, key_jitter: float = 0.35, key_drift: float = 0.12, digraph_speedup: float = 0.72, word_pause: float = 1.5, punctuation_pause: float = 2.1, hesitation_rate: float = 0.03, max_key_gap: float = 1.5, mistype_rate: float = 0.02, mistype_notice: int = 2, layout: KeyboardLayout | str = 'us', click_hold: tuple[float, float] = (0.05, 0.14), aim_pause: tuple[float, float] = (0.04, 0.16), think: tuple[float, float] = (0.15, 0.45), overshoot_probability: float = 0.25, overshoot_min_distance: float = 250.0, idle_moves: bool = False, idle_duration: tuple[float, float] = (0.2, 0.8), idle_amplitude: float = 3.0, actionability_timeout: float = 10.0)
Timing and behaviour parameters for Human.
Every random interval is drawn from a right-skewed (lognormal) distribution; two-value ranges below give its typical span, not flat uniform bounds. Defaults are moderate and not tuned to any particular detector.
Use preset for a named starting point and replace to adjust it.
Attributes:
| Name | Type | Description |
|---|---|---|
move_speed |
float
|
Pointer speed multiplier; values above 1 are faster. |
key_delay |
float
|
Median seconds between keystrokes. |
key_jitter |
float
|
Lognormal sigma of keystroke gaps. |
key_drift |
float
|
Sigma of the per-session typing tempo (one draw per
|
digraph_speedup |
float
|
Gap multiplier for common English letter pairs, which practised typists roll quickly. |
word_pause |
float
|
Median gap multiplier after a space. |
punctuation_pause |
float
|
Median gap multiplier after punctuation or a newline. |
hesitation_rate |
float
|
Probability per keystroke of an extra short hesitation. |
max_key_gap |
float
|
Upper bound on one keystroke gap, in seconds. |
mistype_rate |
float
|
Probability per letter of hitting a neighbouring key first and
correcting it. Ignored when typing with |
mistype_notice |
int
|
Most extra characters typed before a slip is noticed. |
layout |
KeyboardLayout | str
|
Keyboard layout (or registered layout name) for choosing
neighbouring keys; see |
click_hold |
tuple[float, float]
|
Typical range of seconds a button stays pressed. |
aim_pause |
tuple[float, float]
|
Typical range of seconds between arriving and pressing. |
think |
tuple[float, float]
|
Typical range of seconds paused before acting on a target. |
overshoot_probability |
float
|
Chance that a long move overshoots and corrects. |
overshoot_min_distance |
float
|
Moves shorter than this many CSS pixels never overshoot. |
idle_moves |
bool
|
Whether to make small pointer drifts between actions. |
idle_duration |
tuple[float, float]
|
Typical range of seconds of one idle drift. |
idle_amplitude |
float
|
Typical drift radius in CSS pixels. |
actionability_timeout |
float
|
Seconds to wait for a target to become visible, enabled and stable before acting. |
preset
classmethod
¶
preset(name: PresetName = 'default', **overrides: Any) -> HumanConfig
A named preset, optionally with some fields overridden.
default: moderate speed, occasional slips, no idle drift.careful: slower pointer and typing, longer thinking, idle drift between actions, more overshoot on long moves.fast: quick, practised input with fewer slips and pauses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
PresetName
|
Preset name. |
'default'
|
**overrides
|
Any
|
Field values replacing the preset's. |
{}
|
Returns:
| Type | Description |
|---|---|
HumanConfig
|
The configuration. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown preset or an invalid override. |
replace
¶
replace(**changes: Any) -> HumanConfig
A copy with changes applied (validated like a new instance).
Human
¶
Human(page: Any, *, config: HumanConfig | None = None, profile: HumanConfig | None = None, seed: int | None = None, clock: Clock | None = None)
Human-like input for one page. Remembers the pointer position between actions.
Works with native botonomus.cdp.Page and Playwright-compatible pages:
it only uses page.mouse (move, down, up, wheel),
page.keyboard (type, press) and page.evaluate. Targets are
locators from either driver, or (x, y) points.
Before acting on a locator, Human waits until it is visible, enabled
and has a stable box, and brings it into view with wheel scrolling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
page
|
Any
|
The page to drive. |
required |
config
|
HumanConfig | None
|
Behaviour parameters; |
None
|
profile
|
HumanConfig | None
|
Deprecated name for |
None
|
seed
|
int | None
|
Seed for reproducible paths and timing. |
None
|
clock
|
Clock | None
|
Time source; replace it to simulate time in tests. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
pause
async
¶
Sleep for a right-skewed "thinking" interval; sends no CDP traffic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
low
|
float | None
|
Lower typical bound in seconds; |
None
|
high
|
float | None
|
Upper typical bound in seconds; |
None
|
idle
async
¶
Small, low-amplitude pointer drift around the current position.
Does nothing until the pointer has a known position. Never runs longer than
seconds (by default a draw from config.idle_duration).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
float | None
|
Upper bound on the drift's duration. |
None
|
move_to
async
¶
Move the pointer to (x, y) along a curved, eased path.
Long, fast moves sometimes overshoot the target slightly and correct back
(config.overshoot_probability), as aimed human movements do.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Destination x in CSS pixels. |
required |
y
|
float
|
Destination y in CSS pixels. |
required |
target_width
|
float
|
Size of the target, which sets the Fitts's-law duration. |
40.0
|
move_to_locator
async
¶
Bring locator into view, wait until it is actionable, and move into it.
Returns:
| Type | Description |
|---|---|
Point
|
The point reached. |
Raises:
| Type | Description |
|---|---|
NotActionableError
|
If the element does not become visible, enabled and
stable within |
hover
async
¶
Move the pointer over target (a locator or a point) without clicking.
Raises:
| Type | Description |
|---|---|
NotActionableError
|
If a locator target never becomes actionable. |
click
async
¶
Move to target (a locator or a point) and click with a natural hold.
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown button. |
NotActionableError
|
If a locator target never becomes actionable. |
type
async
¶
Type text key by key into the focused element; clicks target first.
Gaps follow a lognormal rhythm with per-session drift, faster common letter
pairs and longer pauses after words and punctuation. With
config.mistype_rate per letter a neighbouring key is hit, noticed a
character or two later, and corrected with backspaces; the field always ends
up containing exactly text appended to what was there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to type. |
required |
target
|
Any | None
|
Optional locator or point to click first. |
None
|
sensitive
|
bool
|
Disable mistakes, for passwords, codes and other secrets where a transient wrong character is unacceptable (it can trigger validation, lockouts or be captured by key loggers on the page). |
False
|
fill
async
¶
Click target, clear it, and type value humanly.
Clearing selects the current text (select_text on the locator) and
presses Backspace; without select_text it presses End and one Backspace
per character. Unlike a driver's fill, the text arrives as keystrokes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
Any
|
A locator for an input, textarea or editable element. |
required |
value
|
str
|
The value to leave in the field. |
required |
sensitive
|
bool
|
Disable mistakes; see |
False
|
press
async
¶
Press key (for example "Enter") after a short reaction pause.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
A key name understood by the page's keyboard. |
required |
scroll
async
¶
Wheel-scroll in several eased increments, like a physical wheel.
KeyboardLayout
dataclass
¶
Physical key rows of a keyboard layout, used to pick neighbouring keys.
Rows are given unshifted, top (number row) to bottom. Two keys are neighbours when they sit next to each other on one row, or overlap horizontally on an adjacent row once the row offsets are applied.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Registry name, for example |
rows |
tuple[str, ...]
|
Unshifted characters of each key row, top to bottom. |
offsets |
tuple[float, ...]
|
Horizontal offset of each row in key widths. |
neighbours
¶
Letters physically adjacent to char, in the same case as char.
Only letters below the number row are returned: a slip onto a digit or symbol key (or an AZERTY number-row accent) is rarer and could change the meaning of structured input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
char
|
str
|
A single character. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The neighbouring letters, or an empty string if |
str
|
on this layout. |
Keystroke
dataclass
¶
One planned keyboard action.
Attributes:
| Name | Type | Description |
|---|---|---|
kind |
KeystrokeKind
|
|
text |
str
|
The character typed, empty for a backspace. |
mistake |
bool
|
Whether this character is the wrong key of a slip. |
correction |
bool
|
Whether this keystroke is part of fixing a slip (the backspaces and the first one after them), which is typed after a noticing pause. |
HumanLocator
¶
HumanLocator(human: Human, locator: Any)
A locator whose interactions go through Human.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
human
|
Human
|
The input engine (shared with the owning |
required |
locator
|
Any
|
The driver's locator. |
required |
click
async
¶
Move along a human path and click; see Human.click.
fill
async
¶
Click, clear and type value keystroke by keystroke.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
The value to leave in the field. |
required |
sensitive
|
bool
|
Disable mistakes (passwords, codes); see |
False
|
type
async
¶
Click the element, then type text humanly after its current content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to type. |
required |
sensitive
|
bool
|
Disable mistakes (passwords, codes); see |
False
|
press
async
¶
Focus the element (without clicking it) and press key.
Focus is moved programmatically, as Playwright's press does, so pressing
a key on a button never also clicks it.
HumanPage
¶
HumanPage(page: Any, *, human: Human | None = None, config: HumanConfig | None = None, seed: int | None = None)
A page wrapper that makes interactions human-like.
Selectors are resolved with the wrapped page's own locator(), so every
selector the driver supports works here. See the module docstring for which
methods are humanized; all other attributes are delegated unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
page
|
Any
|
A native |
required |
human
|
Human | None
|
An existing input engine for |
None
|
config
|
HumanConfig | None
|
Behaviour for a newly created |
None
|
seed
|
int | None
|
Seed for a newly created |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
click
async
¶
Click the element matching selector with a human pointer path.
fill
async
¶
Click, select all, and type value keystroke by keystroke.
Unlike the driver's fill, text is never inserted in one go.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selector
|
str
|
The field. |
required |
value
|
str
|
The value to leave in the field. |
required |
sensitive
|
bool
|
Disable mistakes (passwords, codes); see |
False
|
type
async
¶
Click the element, then type text humanly after its current content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selector
|
str
|
The field. |
required |
text
|
str
|
Text to type. |
required |
sensitive
|
bool
|
Disable mistakes (passwords, codes); see |
False
|
press
async
¶
Press a key on the focused element, or on selector first.
Both press("Enter") and the Playwright form press("#q", "Enter") work.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_or_selector
|
str
|
The key, or a selector when |
required |
key
|
str | None
|
The key to press on that selector's element. |
None
|
scroll
async
¶
Wheel-scroll by delta_y (and delta_x) CSS pixels in eased ticks.
KeystrokeRhythm
¶
KeystrokeRhythm(config: HumanConfig, rng: Random)
Stateful keystroke-gap generator for one typing session.
A tempo factor is drawn once per instance (some sessions type faster than others) and drifts slowly as a mean-reverting random walk between keystrokes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
HumanConfig
|
Timing parameters. |
required |
rng
|
Random
|
Random source. |
required |
gap
¶
Seconds to wait after typing char before the next keystroke.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
char
|
str
|
The character just typed. |
required |
next_char
|
str | None
|
The character about to be typed, if known. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
The gap in seconds, at most |
correction_pause
¶
Seconds between making a slip and starting to correct it.
backspace_gap
¶
Seconds between repeated backspaces, which are faster than typing.
wait_until_actionable
async
¶
wait_until_actionable(locator: Any, *, timeout: float = 10.0, clock: Clock | None = None, require_enabled: bool = True) -> dict[str, float]
Wait until locator is attached, visible, enabled and has a stable box.
Stability means two bounding boxes measured FRAME_INTERVAL apart agree
within half a pixel, so an element still sliding or growing is not targeted.
The enabled check is skipped for locators without is_enabled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
locator
|
Any
|
An |
required |
timeout
|
float
|
Seconds before giving up. |
10.0
|
clock
|
Clock | None
|
Time source; the event loop clock by default. |
None
|
require_enabled
|
bool
|
Whether a disabled element should be waited on. |
True
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
The last measured box. |
Raises:
| Type | Description |
|---|---|
NotActionableError
|
If the element is not actionable within |
get_layout
¶
get_layout(layout: KeyboardLayout | str) -> KeyboardLayout
Resolve a layout name (or pass a layout through unchanged).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout
|
KeyboardLayout | str
|
A registered layout name or a |
required |
Returns:
| Type | Description |
|---|---|
KeyboardLayout
|
The layout. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no layout of that name is registered. |
plan_keystrokes
¶
plan_keystrokes(text: str, layout: KeyboardLayout, mistype_rate: float, rng: Random, *, max_notice_delay: int = 2) -> list[Keystroke]
Plan the keystrokes for text, including occasional corrected slips.
With probability mistype_rate per letter, a neighbouring key is typed
instead. The slip is noticed after 0 to max_notice_delay further characters,
deleted with the matching number of backspaces, and the intended characters are
typed again. Replaying the plan on an empty field always yields exactly text.
A slip is never left pending across a newline, carriage return or tab, since those could submit a form or move focus first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text that must end up typed. |
required |
layout
|
KeyboardLayout
|
Layout used to choose the neighbouring key. |
required |
mistype_rate
|
float
|
Probability of a slip per letter, in |
required |
rng
|
Random
|
Random source. |
required |
max_notice_delay
|
int
|
Most extra characters typed before the slip is noticed. |
2
|
Returns:
| Type | Description |
|---|---|
list[Keystroke]
|
The keystrokes in order. |
register_layout
¶
register_layout(layout: KeyboardLayout) -> None
Make layout available by name, replacing any layout of the same name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout
|
KeyboardLayout
|
The layout to register. |
required |
bezier_path
¶
A cubic Bézier path from start to end with eased progress.
Control points bow the curve perpendicular to the straight line by a random, slightly asymmetric amount, as a wrist-driven movement does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Point
|
Starting point in CSS pixels. |
required |
end
|
Point
|
Destination; always the exact last point. |
required |
rng
|
Random
|
Random source (seed it for reproducible paths). |
required |
steps
|
int | None
|
Number of points; derived from distance when |
None
|
Returns:
| Type | Description |
|---|---|
list[Point]
|
Points after |
eased_weights
¶
count positive weights summing to 1, small at both ends (sine easing).
movement_duration
¶
Seconds to reach a target, following Fitts's law.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
distance
|
float
|
Travel distance in CSS pixels. |
required |
width
|
float
|
Target size along the approach; smaller targets take longer. |
required |
speed
|
float
|
Multiplier; values above 1 are faster. |
required |
rng
|
Random
|
Random source for natural variation. |
required |
target_point
¶
A point near the centre of box, never on its outer 20% border.
bounded_lognormal
¶
A lognormal draw whose central ~95% falls in [low, high].
The median is the geometric mean of the bounds, so the distribution is skewed to the right like human reaction times. Draws outside the range are clamped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rng
|
Random
|
Random source. |
required |
low
|
float
|
Lower typical bound, greater than zero. |
required |
high
|
float
|
Upper typical bound. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Seconds (or any positive quantity) in |
key_delays
¶
key_delays(text: str, profile: HumanConfig, rng: Random) -> list[float]
Gaps after each character of text from a fresh KeystrokeRhythm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to be typed. |
required |
profile
|
HumanConfig
|
Timing parameters. |
required |
rng
|
Random
|
Random source. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
One delay in seconds per character, each at most |