🖱️ AirMouse Core (airmouse-core)
High-performance, ultra-low-latency remote mouse and input server engine for Python.
Seamlessly turns Android, iOS, or web client devices into responsive air mice with hardware-grade cursor smoothing, robust replay-attack mitigation, and TLS 1.2+ encryption.
Key Features • Installation • Quick Start CLI • Python API • Architecture • Protocol V2 • Testing
⚡ Key Features
- 🔒 Enterprise-Grade TLS Security:
- Full TLS 1.2+ encryption on both TCP and WebSocket connections.
- Automatic self-signed X.509 certificate provisioning with persistent key storage (
0600permissions) to prevent TLS pinning breaks on server reboot.
- 📱 Zero-Friction Terminal QR Pairing:
- Out-of-the-box CLI displays ANSI QR codes right in your terminal for 1-second camera scan pairing from mobile devices.
- 🎯 1€ (One Euro) Adaptive Smoothing:
- Implements Casiez et al. adaptive low-pass filter algorithm to eliminate micro-jitter during slow precision movements while eliminating lag during fast sweeps.
- 🌐 LAN Auto-Discovery:
- Multithreaded UDP broadcast responder with cryptographic challenge-response nonces for instantaneous zero-configuration LAN discovery.
- 🧵 Thread-Safe Actuation Decoupling:
- Completely decouples high-frequency network I/O (
asyncio) from OS windowing/mouse controller drivers (pynput) via an internal thread-safe queue.
- Completely decouples high-frequency network I/O (
- 🛡️ Anti-Replay Attack Protection:
- Enforces sliding timestamp freshness windows and per-session monotonic sequence numbering.
- 📦 PEP 561 Compliant:
- Full typing support with
py.typedmarker for static analysis with mypy, pyright, and modern IDE auto-complete.
- Full typing support with
📥 Installation
Install the stable release directly from PyPI:
pip install airmouse-core
Or install with development dependencies:
pip install airmouse-core[dev]
🚀 Quick Start CLI
Run the production server directly from the command line:
airmouse-server --port 8080 --ws-port 8081 --udp-port 8083 --qr
CLI Options:
| Flag | Description | Default |
|---|---|---|
--host |
Bind interface address | 0.0.0.0 |
--port |
TCP listening port | 8080 |
--ws-port |
WebSocket listening port | 8081 |
--udp-port |
UDP LAN discovery broadcast port | 8083 |
--qr |
Render terminal ANSI QR code for mobile pairing | False |
--no-tls |
Disable TLS encryption | False (TLS enabled) |
--no-smoothing |
Disable 1€ adaptive filter | False (Smoothing enabled) |
--sensitivity |
Mouse cursor speed multiplier | 1.0 |
--name |
Friendly server display name | AirMouse Server |
💻 Python API
airmouse-core exposes a clean, intuitive public API:
import asyncio
from airmouse import (
AirMouseServer,
OneEuroFilter,
UDPJitterBuffer,
AuthManager,
ProtocolParser,
)
async def main():
# 1. Initialize server
server = AirMouseServer(
host="0.0.0.0",
tcp_port=8080,
ws_port=8081,
udp_port=8083,
enable_tls=True,
sensitivity=1.2,
smoothing=True,
)
# 2. Register lifecycle and input event callbacks
server.on_connect(lambda session_id: print(f"Client connected: {session_id}"))
server.on_disconnect(lambda session_id: print(f"Client disconnected: {session_id}"))
server.on_move(lambda dx, dy: print(f"Motion: dx={dx:.2f}, dy={dy:.2f}"))
server.on_click(lambda button: print(f"Click: {button}"))
# 3. Start server
await server.start()
print("AirMouse Server is running. Press Ctrl+C to exit.")
try:
await asyncio.Event().wait()
finally:
await server.stop()
if __name__ == "__main__":
asyncio.run(main())
🏗️ Architecture
Mobile / Web Client (Android / iOS / Browser)
│
┌───────────┴───────────┐
▼ ▼
[TCP TLS 1.2+] [WebSocket TLS]
│ │
└───────────┬───────────┘
│ (Asyncio Network Loop)
▼
ProtocolParser (V2)
[Replay & Bounds Validation]
│
▼
Thread-Safe Command Queue
│
▼
MouseActuatorThread
[OneEuroFilter Smoothing]
│
▼
OS Cursor Actuation (pynput)
📡 Protocol V2 Specification
Every wire packet follows the strict canonical V2 envelope:
{
"v": 2,
"type": "move",
"seq": 1024,
"ts": 1729771200000,
"id": "optional-request-id",
"payload": {
"dx": 12.5,
"dy": -3.2,
"dt": 0.016
}
}
Supported Message Types:
hello: Initial handshake pairing request carrying HMAC token.welcome: Server approval response.move: Relative mouse coordinates (dx,dy,dt).click: Mouse button clicks (left,right,middle,double).scroll: Wheel scroll offset (delta).key: Keyboard input events (key,modifiers).discover/offer: UDP LAN pairing handshake.ping/pong: Heartbeat and connection keep-alive.
🧪 Test Suite
The test suite covers 100% of the core functionality with high test coverage:
cd pc/airmouse_py
pytest --cov=. --cov-report=term-missing tests
Results:
- 46 passing unit and integration tests
- 88% code coverage
- Automated testing for replay protection, crypto HMAC validation, TLS X.509 generation, and socket concurrency.
📄 License
This project is licensed under the MIT License.
Metadata
Release files for airmouse-core 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| airmouse_core-2.0.0.tar.gz | 39.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| airmouse_core-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.8 kB
Release files / airmouse_core-2.0.0.tar.gz
| Download URL | airmouse_core-2.0.0.tar.gz |
|---|---|
| Size | 39.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
24f75b3485a035560c2218a2d88d928aaa024eeabaf50e32359b3ad343f24df7
|
|
BLAKE2b-256 checksum How to use checksums |
887c056a2dd87fa7152cd6c63d4dc61e94e26193b2159b947e84ccdbfd68c0d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / airmouse_core-2.0.0-py3-none-any.whl
| Download URL | airmouse_core-2.0.0-py3-none-any.whl |
|---|---|
| Size | 31.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b9611f23d80498fef9cd904c1c810ea233a67141736951fd82a4e66190040d29
|
|
BLAKE2b-256 checksum How to use checksums |
79215bc3412c054ca46f996f1fd662b144fb264c86407071db28e61fba9ad4af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Security for airmouse-core 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.