Async Usageο
The Makcu library provides full async/await support for modern Python applications. The async API offers the same functionality as the synchronous version with added benefits for concurrent operations.
Why Use Async?ο
Benefits: * Execute multiple mouse operations in parallel * Non-blocking integration with async applications * Better resource utilization in I/O-bound applications * Modern Python patterns with async/await
When to Use Async: * Building GUI applications with async frameworks * Creating bots or automation tools * Integrating with async web applications * Need parallel mouse operations
Creating an Async Controllerο
Basic Async Connection:
import asyncio
from makcu import create_async_controller
async def main():
# Create async controller
makcu = await create_async_controller(debug=True)
# Use the controller
await makcu.click(MouseButton.LEFT)
# Don't forget to disconnect
await makcu.disconnect()
asyncio.run(main())
Using Async Context Managers (Recommended):
import asyncio
from makcu import create_async_controller, MouseButton
async def main():
# Automatic connection and cleanup
async with await create_async_controller(debug=True) as makcu:
await makcu.click(MouseButton.LEFT)
await makcu.move(100, 50)
# Automatically disconnected
asyncio.run(main())
Async Mouse Operationsο
All mouse operations support async/await:
Button Control:
async def button_demo(makcu):
# Basic clicking
await makcu.click(MouseButton.LEFT)
await makcu.double_click(MouseButton.RIGHT)
# Press and release
await makcu.press(MouseButton.MIDDLE)
await asyncio.sleep(1.0) # Hold for 1 second
await makcu.release(MouseButton.MIDDLE)
Movement:
async def movement_demo(makcu):
# Basic movement
await makcu.move(100, 50)
# Smooth movement
await makcu.move_smooth(200, 100, segments=30)
# Bezier curves
await makcu.move_bezier(150, 150, segments=25, ctrl_x=75, ctrl_y=200)
Scrolling:
async def scroll_demo(makcu):
await makcu.scroll(5) # Scroll up
await makcu.scroll(-3) # Scroll down
Parallel Operationsο
Execute Multiple Commands Simultaneously:
import asyncio
from makcu import create_async_controller, MouseButton
async def parallel_demo():
async with await create_async_controller() as makcu:
# Execute multiple operations at once
await asyncio.gather(
makcu.move(100, 0),
makcu.click(MouseButton.LEFT),
makcu.scroll(-1)
)
asyncio.run(parallel_demo())
Sequential vs Parallel Timing:
async def timing_comparison():
async with await create_async_controller() as makcu:
# Sequential (slower)
start = time.time()
await makcu.move(50, 0)
await makcu.click(MouseButton.LEFT)
await makcu.move(-50, 0)
sequential_time = time.time() - start
# Parallel (faster)
start = time.time()
await asyncio.gather(
makcu.move(50, 0),
makcu.click(MouseButton.LEFT),
makcu.move(-50, 0)
)
parallel_time = time.time() - start
print(f"Sequential: {sequential_time:.3f}s")
print(f"Parallel: {parallel_time:.3f}s")
Async Locking Operationsο
async def locking_demo():
async with await create_async_controller() as makcu:
# Lock buttons and axes
await makcu.lock(MouseButton.LEFT)
await makcu.lock("X") # Lock X-axis
# Check lock states
left_locked = await makcu.is_locked(MouseButton.LEFT)
x_locked = await makcu.is_locked("X")
print(f"Left button locked: {left_locked}")
print(f"X-axis locked: {x_locked}")
# Unlock
await makcu.unlock(MouseButton.LEFT)
await makcu.unlock("X")
Connection Managementο
Connection Status:
async def connection_demo():
makcu = await create_async_controller()
if await makcu.is_connected():
print("Device connected")
else:
print("Device not connected")
await makcu.connect() # Manual connection
Auto-Reconnection with Callbacks:
async def auto_reconnect_demo():
async def on_connection_change(connected: bool):
if connected:
print("Device reconnected!")
else:
print("Device disconnected!")
makcu = await create_async_controller(auto_reconnect=True)
# Set connection callback
@makcu.on_connection_change
async def handle_connection(connected):
await on_connection_change(connected)
# Your application continues...
# Reconnection happens automatically
Error Handling in Asyncο
from makcu import MakcuError, MakcuConnectionError, MakcuTimeoutError
async def error_handling_demo():
try:
async with await create_async_controller() as makcu:
await makcu.click(MouseButton.LEFT)
except MakcuConnectionError as e:
print(f"Async connection failed: {e}")
except MakcuTimeoutError as e:
print(f"Async command timed out: {e}")
except MakcuError as e:
print(f"General async error: {e}")
Complete Async Exampleο
Hereβs a comprehensive async example:
import asyncio
from makcu import create_async_controller, MouseButton
async def advanced_async_demo():
"""Demonstrates advanced async Makcu usage."""
async def button_monitor_task(makcu):
"""Background task to monitor button presses."""
async def on_button(button, pressed):
if pressed:
print(f"Detected: {button.name} pressed")
makcu.set_button_callback(on_button)
await makcu.enable_button_monitoring(True)
# Monitor for 30 seconds
await asyncio.sleep(30)
await makcu.enable_button_monitoring(False)
async def mouse_actions_task(makcu):
"""Main mouse control task."""
# Warm-up clicks
await asyncio.gather(*[
makcu.click(MouseButton.LEFT) for _ in range(5)
])
# Smooth movement sequence
movements = [
(100, 0), (0, 100), (-100, 0), (0, -100)
]
for x, y in movements:
await makcu.move_smooth(x, y, segments=20)
await asyncio.sleep(0.5)
# Parallel operations
await asyncio.gather(
makcu.click(MouseButton.RIGHT),
makcu.scroll(-2),
makcu.move(50, 25)
)
# Main async execution
async with await create_async_controller(debug=True) as makcu:
print("Starting advanced async demo...")
# Run tasks concurrently
await asyncio.gather(
button_monitor_task(makcu),
mouse_actions_task(makcu)
)
print("Async demo completed!")
# Run the demo
asyncio.run(advanced_async_demo())
Integration Examplesο
With FastAPI:
from fastapi import FastAPI
from makcu import create_async_controller, MouseButton
app = FastAPI()
makcu_controller = None
@app.on_event("startup")
async def startup():
global makcu_controller
makcu_controller = await create_async_controller()
@app.post("/click/{button}")
async def click_button(button: str):
button_enum = getattr(MouseButton, button.upper())
await makcu_controller.click(button_enum)
return {"status": "clicked", "button": button}
@app.post("/move")
async def move_mouse(x: int, y: int):
await makcu_controller.move(x, y)
return {"status": "moved", "x": x, "y": y}
With AsyncIO Event Loop:
import asyncio
from makcu import create_async_controller, MouseButton
class MakcuBot:
def __init__(self):
self.makcu = None
self.running = False
async def start(self):
self.makcu = await create_async_controller(auto_reconnect=True)
self.running = True
# Start background tasks
await asyncio.gather(
self.monitor_buttons(),
self.periodic_actions()
)
async def monitor_buttons(self):
await self.makcu.enable_button_monitoring(True)
while self.running:
await asyncio.sleep(0.1)
async def periodic_actions(self):
while self.running:
await self.makcu.move(1, 0) # Tiny movement
await asyncio.sleep(10) # Every 10 seconds
# Usage
async def main():
bot = MakcuBot()
await bot.start()
asyncio.run(main())
Performance Considerationsο
Async Performance Tips:
# Good: Use gather for parallel operations
await asyncio.gather(
makcu.click(MouseButton.LEFT),
makcu.move(50, 0),
makcu.scroll(-1)
)
# Avoid: Sequential awaits when parallel is possible
await makcu.click(MouseButton.LEFT)
await makcu.move(50, 0)
await makcu.scroll(-1)
Concurrent Limits:
# Limit concurrent operations to avoid overwhelming device
semaphore = asyncio.Semaphore(5)
async def limited_click():
async with semaphore:
await makcu.click(MouseButton.LEFT)
# Execute many clicks with concurrency limit
tasks = [limited_click() for _ in range(100)]
await asyncio.gather(*tasks)
Next Stepsο
Advanced Features - Advanced async patterns and customization
Examples - More async examples and real-world applications