Windows SendInput wrapper for keyboard and mouse simulation
Project description
scanput
Lightweight Windows Keyboard & Mouse input library using hardware scan codes.
Unlike existing libraries like pyautogui that use virtual key presses, scanput uses hardware scan codes making them indistinguishable* from physical hardware keypresses to most applications.
While the AutoHotKey Python library does offer hardware scan code inputs, the library requires having AutoHotKey installed and pointing your script to the executable path. It then spawns a new AutoHotKey.exe subprocess every time you perform an action - not exactly lightweight.
scanput is designed to be lightweight and requires zero third-party dependencies.
*Technically, Windows sets the LLMHF_INJECTED flag on synthesized input events to indicate they originated from SendInput rather than a physical device. It is rare for applications to check this flag, but it is possible. Full reference here
Installation
pip install scanput
Alternatively, you could save scanput.py to your project's root directory and import scanput. It's literally a single file that needs importing:
cd my-project
curl https://raw.githubusercontent.com/sam-howle/scanput/refs/heads/main/scanput.py -o scanput.py
Usage
A more detailed guide can be found in demo.py.
Key Presses
All button pressing & mouse clicking functions require both a press and a release. Pressing a key without releasing it will result in the key being held down indefinately. It is recommended to add a short timing delay between presses. For example:
HOLD = 0.08
key_down("k")
time.sleep(HOLD)
key_up("k")
The above example presses the k key and holds it for 0.08 seconds before releasing.
For a list of key aliases, run the following line:
print(list(KEY_ALIASES.keys()))
Additionally, key_down() and key_up() accept either a key name string or a raw Windows Virtual Key code as an integer, allowing direct specification of any VK code not covered by the named aliases. The Windows Virtual Key code is converted to a hardware scan code before input is performed. A full list of Windows VK integers can be found at the following link:
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Mouse Clicks
Similarly, mouse clicks also take a press & release approach:
HOLD = 0.08
print("Left click.")
left_down()
time.sleep(HOLD)
left_up()
print("Right click.")
right_down()
time.sleep(HOLD)
right_up()
Mouse Movement
There are only two mouse movement functions: get_cursor_position() and set_cursor_position(x,y). The following snippet obtains the current mouse position, and offsets it by an (x,y) value of (300,150) pixels:
x, y = get_cursor_position()
print(f"Current mouse position: ({x}, {y})")
dest_x, dest_y = x + 300, y - 150
print(f"Teleporting mouse to ({dest_x}, {dest_y})")
set_cursor_position(dest_x, dest_y)
Please note that the Y axis for monitor pixel coordinates starts with 0 being the top of the screen, rather than the bottom. That means the coordinate (0,0) is the top-left monitor pixel. While unintuitive, it is consistent with how monitor pixel coordinates have always worked starting with early CRTs.
Screen Resolution
The get_screen_resolution() function returns the primary monitor's resolution as (width, height), which is handy for clamping cursor coordinates or calculating positions relative to the screen size:
width, height = get_screen_resolution()
print(f"Screen resolution: {width}x{height}")
center_x, center_y = width // 2, height // 2
print(f"Teleporting mouse to center of screen: ({center_x}, {center_y})")
set_cursor_position(center_x, center_y)
Toggle Key States
The get_toggle_key_state() function can be used to let your script know the current state of the capslock, numlock, and scrolllock keys:
get_toggle_key_state("capslock") # 1 or 0
get_toggle_key_state("numlock") # 1 or 0
get_toggle_key_state("scrolllock") # 1 or 0
get_toggle_key_state(0x14) # same as capslock by VK int
Be aware that this function is only meaningful for toggle keys. Passing modifier keys like shift or alt will always return 0.
And that's really all there is to it.
You can press buttons. And you can release buttons. You can move the mouse. And you can find out where the mouse is. You can click mice. And you can release mouse clicks. The world is your oyster. Crack it open and slurp out its innards.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scanput-0.2.1.tar.gz.
File metadata
- Download URL: scanput-0.2.1.tar.gz
- Upload date:
- Size: 6.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83689ae39f17cc198bb933ed3f645846f8badf1a9bd4a6646375cde3d71eb4a3
|
|
| MD5 |
8ad343a330540db8ade0060263cd7e1a
|
|
| BLAKE2b-256 |
6a941e338a9b07d13969fb43fae80e59fc030cb7c638393fe412137b6c0c7e84
|
File details
Details for the file scanput-0.2.1-py3-none-any.whl.
File metadata
- Download URL: scanput-0.2.1-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca2506e761e407437d92bdf0695b553ef0532fb35fb965105fe8fb4b9508e434
|
|
| MD5 |
25f9dca926f7a185071f1cb9040d193d
|
|
| BLAKE2b-256 |
aeec4b31c1c69325cea17b1dfec8782f9a912992c8662f28ecf10e7dfa58e59b
|