Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

Monitor and control user input devices

Project Description

pynput

This library allows you to control and monitor input devices.

Currently, mouse and keyboard input and monitoring are supported.

See here for the full documentation.

Controlling the mouse

Use pynput.mouse.Controller like this:

from pynput.mouse import Button, Controller

mouse = Controller()

# Read pointer position
print('The current pointer position is {0}'.format(
    mouse.position))

# Set pointer position
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
    mouse.position))

# Move pointer relative to current position
mouse.move(5, -5)

# Press and release
mouse.press(Button.left)
mouse.release(Button.left)

# Double click; this is different from pressing and releasing
# twice on Mac OSX
mouse.click(Button.left, 2)

# Scroll two steps down
mouse.scroll(0, 2)

Monitoring the mouse

Use pynput.mouse.Listener like this:

from pynput import mouse

def on_move(x, y):
    print('Pointer moved to {0}'.format(
        (x, y)))

def on_click(x, y, button, pressed):
    print('{0} at {1}'.format(
        'Pressed' if pressed else 'Released',
        (x, y)))
    if not pressed:
        # Stop listener
        return False

def on_scroll(x, y, dx, dy):
    print('Scrolled {0} at {1}'.format(
        'down' if dy < 0 else 'up',
        (x, y)))

# Collect events until released
with mouse.Listener(
        on_move=on_move,
        on_click=on_click,
        on_scroll=on_scroll) as listener:
    listener.join()

A mouse listener is a threading.Thread, and all callbacks will be invoked from the thread.

Call pynput.mouse.Listener.stop from anywhere, raise StopException or return False from a callback to stop the listener.

The mouse listener thread

The listener callbacks are invoked directly from an operating thread on some platforms, notably Windows.

This means that long running procedures and blocking operations should not be invoked from the callback, as this risks freezing input for all processes.

A possible workaround is to just dispatch incoming messages to a queue, and let a separate thread handle them.

Handling mouse listener errors

If a callback handler raises an exception, the listener will be stopped. Since callbacks run in a dedicated thread, the exceptions will not automatically be reraised.

To be notified about callback errors, call Thread.join on the listener instance:

from pynput import mouse

class MyException(Exception): pass

def on_click(x, y, button, pressed):
    if button == mouse.Button.left:
        raise MyException(button)

# Collect events until released
with mouse.Listener(
        on_click=on_click) as listener:
    try:
        listener.join()
    except MyException as e:
        print('{0} was clicked'.format(e.args[0]))

Controlling the keyboard

Use pynput.keyboard.Controller like this:

from pynput.keyboard import Key, Controller

keyboard = Controller()

# Press and release space
keyboard.press(Key.space)
keyboard.release(Key.space)

# Type a lower case A; this will work even if no key on the
# physical keyboard is labelled 'A'
keyboard.press('a')
keyboard.release('a')

# Type two upper case As
keyboard.press('A')
keyboard.release('A')
with keyboard.pressed(Key.shift):
    keyboard.press('a')
    keyboard.release('a')

# Type 'Hello World' using the shortcut type method
keyboard.type('Hello World')

Monitoring the keyboard

Use pynput.keyboard.Listener like this:

from pynput import keyboard

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

A keyboard listener is a threading.Thread, and all callbacks will be invoked from the thread.

Call pynput.keyboard.Listener.stop from anywhere, raise StopException or return False from a callback to stop the listener.

The key parameter passed to callbacks is a pynput.keyboard.Key, for special keys, a pynput.keyboard.KeyCode for normal alphanumeric keys, or just None for unknown keys.

The keyboard listener thread

The listener callbacks are invoked directly from an operating thread on some platforms, notably Windows.

This means that long running procedures and blocking operations should not be invoked from the callback, as this risks freezing input for all processes.

A possible workaround is to just dispatch incoming messages to a queue, and let a separate thread handle them.

Handling keyboard listener errors

If a callback handler raises an exception, the listener will be stopped. Since callbacks run in a dedicated thread, the exceptions will not automatically be reraised.

To be notified about callback errors, call Thread.join on the listener instance:

from pynput import keyboard

class MyException(Exception): pass

def on_press(key):
    if key == keyboard.Key.esc:
        raise MyException(key)

# Collect events until released
with keyboard.Listener(
        on_press=on_press) as listener:
    try:
        listener.join()
    except MyException as e:
        print('{0} was pressed'.format(e.args[0]))

Release Notes

v1.3.7 - Xorg corrections

  • Include mouse buttons up to 30 for Xorg.

v1.3.6 - win32 corrections

  • Corrected double delivery of fake keyboard events on Windows.
  • Corrected handling of synthetic unicode keys on Windows.

v1.3.5 - Corrected dependencies again

  • Reverted changes in 1.3.3.
  • Corrected platform specifier for Python 2 on Linux.

v1.3.4 - Xorg corrections

  • Corrected bounds check for values on Xorg.

v1.3.3 - Make dependencies non-optional

  • Made platform depdendencies non-optional.

v1.3.2 - Fix for button click on Mac

  • Corrected regression from previous release where button clicks would crash the Mac mouse listener.

v1.3.1 - Fixes for unknown buttons on Linux

  • Fall back on Button.unknown for unknown mouse buttons in Xorg mouse listener.

v1.3 - Platform specific features

  • Added ability to stop event propagation on Windows. This will prevent events from reaching other applications.
  • Added ability to ignore events on Windows. This is a workaround for systems where the keyboard monitor interferes with normal keyboard events.
  • Added ability to modify events on OSX. This allows intercepting and altering input events before they reach other applications.
  • Corrected crash on OSX when some types of third party input sources are installed.

v1.2 - Improved error handling

  • Allow catching exceptions thrown from listener callbacks. This changes the API, as joining a listener now potentially raises unhandled exceptions, and unhandled exceptions will stop listeners.
  • Added support for the numeric keypad on Linux.
  • Improved documentation.
  • Thanks to jollysean and gilleswijnker for their input!

v1.1.7 - Handle middle button on Windows

  • Listen for and dispatch middle button mouse clicks on Windows.

v1.1.6 - Corrected context manager for pressing keys

  • Corrected bug in pynput.keyboard.Controller.pressed which caused it to never release the key. Many thanks to Toby Southwell!

v1.1.5 - Corrected modifier key combinations on Linux

  • Corrected handling of modifier keys to allow them to be composable on Linux.

v1.1.4 - Small bugfixes

  • Corrected error generation when GetKeyboardState fails.
  • Make sure to apply shift state to borrowed keys on X.
  • Use pylint.

v1.1.3 - Changed Xlib backend library

  • Changed Xlib library.

v1.1.2 - Added missing type for Python 2

  • Added missing LPDWORD for Python 2 on Windows.

v1.1.1 - Fixes for listeners and controllers on Windows

  • Corrected keyboard listener on Windows. Modifier keys and other keys changing the state of the keyboard are now handled correctly.
  • Corrected mouse click and release on Windows.
  • Corrected code samples.

v1.1 - Simplified usage on Linux

  • Propagate import errors raised on Linux to help troubleshoot missing Xlib module.
  • Declare python3-xlib as dependency on Linux for Python 3.

v1.0.6 - Universal wheel

  • Make sure to build a universal wheel for all python versions.

v1.0.5 - Fixes for dragging on OSX

  • Corrected dragging on OSX.
  • Added scroll speed constant for OSX to correct slow scroll speed.

v1.0.4 - Fixes for clicking and scrolling on Windows

  • Corrected name of mouse input field when sending click and scroll events.

v1.0.3 - Fixes for Python 3 on Windows

  • Corrected use of ctypes on Windows.

v1.0.2 - Fixes for thread identifiers

  • Use thread identifiers to identify threads, not Thread instances.

v1.0.1 - Fixes for Python 3

  • Corrected bugs which prevented the library from being used on Python 3.

v1.0 - Stable Release

  • Changed license to LGPL.
  • Corrected minor bugs and inconsistencies.
  • Corrected and extended documentation.

v0.6 - Keyboard Monitor

  • Added support for monitoring the keyboard.
  • Corrected wheel packaging.
  • Corrected deadlock when stopping a listener in some cases on X.
  • Corrected key code constants on Mac OSX.
  • Do not intercept events on Mac OSX.

v0.5.1 - Do not die on dead keys

  • Corrected handling of dead keys.
  • Corrected documentation.

v0.5 - Keyboard Modifiers

  • Added support for modifiers.

v0.4 - Keyboard Controller

  • Added keyboard controller.

v0.3 - Cleanup

  • Moved pynput.mouse.Controller.Button to top-level.

v0.2 - Initial Release

  • Support for controlling the mouse on Linux, Mac OSX and Windows.
  • Support for monitoring the mouse on Linux, Mac OSX and Windows.
Release History

Release History

This version
History Node

1.3.7

History Node

1.3.6

History Node

1.3.5

History Node

1.3.4

History Node

1.3.3

History Node

1.3.2

History Node

1.3.1

History Node

1.3

History Node

1.2

History Node

1.1.7

History Node

1.1.6

History Node

1.1.5

History Node

1.1.4

History Node

1.1.3

History Node

1.1.2

History Node

1.1.1

History Node

1.1

History Node

1.0.6

History Node

1.0.5

History Node

1.0.4

History Node

1.0.3

History Node

1.0.2

History Node

1.0.1

History Node

1.0

History Node

0.6

History Node

0.5.1

History Node

0.5

History Node

0.4

History Node

0.3

History Node

0.2

History Node

0.1

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
pynput-1.3.7-py2.py3-none-any.whl (71.1 kB) Copy SHA256 Checksum SHA256 3.5 Wheel Aug 23, 2017
pynput-1.3.7-py3.5.egg (151.7 kB) Copy SHA256 Checksum SHA256 3.5 Egg Aug 23, 2017

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting