Package: pynput
pynputThis library allows you to control and monitor input devices.Currently, mouse and keyboard input and monitoring are supported.Seeherefor the full
documentation.Controlling the mouseUsepynput.mouse.Controllerlike 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 macOS
mouse.click(Button.left, 2)

# Scroll two steps down
mouse.scroll(0, 2)Monitoring the mouseUsepynput.mouse.Listenerlike 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()

# ...or, in a non-blocking fashion:
listener = mouse.Listener(
    on_move=on_move,
    on_click=on_click,
    on_scroll=on_scroll)
listener.start()A mouse listener is athreading.Thread, and all callbacks will be invoked
from the thread.Callpynput.mouse.Listener.stopfrom anywhere, raiseStopExceptionor
returnFalsefrom a callback to stop the listener.When using the non-blocking version above, the current thread will continue
executing. This might be necessary when integrating with other GUI frameworks
that incorporate a main-loop, but when run from a script, this will cause the
program to terminate immediately.The mouse listener threadThe listener callbacks are invoked directly from an operating thread on some
platforms, notablyWindows.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 errorsIf 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, callThread.joinon 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]))Toggling event listening for the mouse listenerOncepynput.mouse.Listener.stophas been called, the listener cannot be
restarted, since listeners are instances ofthreading.Thread.If your application requires toggling listening events, you must either add an
internal flag to ignore events when not required, or create a new listener when
resuming listening.Synchronous event listening for the mouse listenerTo simplify scripting, synchronous event listening is supported through the
utility classpynput.mouse.Events. This class supports reading single
events in a non-blocking fashion, as well as iterating over all events.To read a single event, use the following code:from pynput import mouse

# The event listener will be running in this block
with mouse.Events() as events:
    # Block at most one second
    event = events.get(1.0)
    if event is None:
        print('You did not interact with the mouse within one second')
    else:
        print('Received event {}'.format(event))To iterate over mouse events, use the following code:from pynput import mouse

# The event listener will be running in this block
with mouse.Events() as events:
    for event in events:
        if event.button == mouse.Button.right:
            break
        else:
            print('Received event {}'.format(event))Please note that the iterator method does not support non-blocking operation,
so it will wait for at least one mouse event.The events will be instances of the inner classes found inpynput.mouse.Events.Ensuring consistent coordinates between listener and controller on WindowsRecent versions of _Windows_ support running legacy applications scaled when
the system scaling has been increased beyond 100%. This allows old applications
to scale, albeit with a blurry look, and avoids tiny, unusable user interfaces.This scaling is unfortunately inconsistently applied to a mouse listener and a
controller: the listener will receive physical coordinates, but the controller
has to work with scaled coordinates.This can be worked around by telling Windows that your application is DPI
aware. This is a process global setting, so _pynput_ cannot do it
automatically. Do enable DPI awareness, run the following code:import ctypes


PROCESS_PER_MONITOR_DPI_AWARE = 2

ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)Controlling the keyboardUsepynput.keyboard.Controllerlike 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 keyboardUsepynput.keyboard.Listenerlike 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()

# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release)
listener.start()A keyboard listener is athreading.Thread, and all callbacks will be
invoked from the thread.Callpynput.keyboard.Listener.stopfrom anywhere, raiseStopExceptionor returnFalsefrom a callback to stop the listener.Thekeyparameter passed to callbacks is apynput.keyboard.Key, for
special keys, apynput.keyboard.KeyCodefor normal alphanumeric keys, or
justNonefor unknown keys.When using the non-blocking version above, the current thread will continue
executing. This might be necessary when integrating with other GUI frameworks
that incorporate a main-loop, but when run from a script, this will cause the
program to terminate immediately.The keyboard listener threadThe listener callbacks are invoked directly from an operating thread on some
platforms, notablyWindows.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 errorsIf 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, callThread.joinon 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]))Toggling event listening for the keyboard listenerOncepynput.keyboard.Listener.stophas been called, the listener cannot be
restarted, since listeners are instances ofthreading.Thread.If your application requires toggling listening events, you must either add an
internal flag to ignore events when not required, or create a new listener when
resuming listening.Synchronous event listening for the keyboard listenerTo simplify scripting, synchronous event listening is supported through the
utility classpynput.keyboard.Events. This class supports reading single
events in a non-blocking fashion, as well as iterating over all events.To read a single event, use the following code:from pynput import keyboard

# The event listener will be running in this block
with keyboard.Events() as events:
    # Block at most one second
    event = events.get(1.0)
    if event is None:
        print('You did not press a key within one second')
    else:
        print('Received event {}'.format(event))To iterate over keyboard events, use the following code:from pynput import keyboard

# The event listener will be running in this block
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            break
        else:
            print('Received event {}'.format(event))Please note that the iterator method does not support non-blocking operation,
so it will wait for at least one keyboard event.The events will be instances of the inner classes found inpynput.keyboard.Events.Global hotkeysA common use case for keyboard monitors is reacting to global hotkeys. Since a
listener does not maintain any state, hotkeys involving multiple keys must
store this state somewhere.pynputprovides the classpynput.keyboard.HotKeyfor this purpose. It
contains two methods to update the state, designed to be easily interoperable
with a keyboard listener:pynput.keyboard.HotKey.pressandpynput.keyboard.HotKey.releasewhich can be directly passed as listener
callbacks.The intended usage is as follows:from pynput import keyboard

def on_activate():
    print('Global hotkey activated!')

def for_canonical(f):
    return lambda k: f(l.canonical(k))

hotkey = keyboard.HotKey(
    keyboard.HotKey.parse('<ctrl>+<alt>+h'),
    on_activate)
with keyboard.Listener(
        on_press=for_canonical(hotkey.press),
        on_release=for_canonical(hotkey.release)) as l:
    l.join()This will create a hotkey, and then use a listener to update its state. Once
all the specified keys are pressed simultaneously,on_activatewill be
invoked.Note that keys are passed throughpynput.keyboard.Listener.canonicalbefore
being passed to theHotKeyinstance. This is to remove any modifier state
from the key events, and to normalise modifiers with more than one physical
button.The methodpynput.keyboard.HotKey.parseis a convenience function to
transform shortcut strings to key collections. Please see its documentation for
more information.To register a number of global hotkeys, use the convenience classpynput.keyboard.GlobalHotKeys:from pynput import keyboard

def on_activate_h():
    print('<ctrl>+<alt>+h pressed')

def on_activate_i():
    print('<ctrl>+<alt>+i pressed')

with keyboard.GlobalHotKeys({
        '<ctrl>+<alt>+h': on_activate_h,
        '<ctrl>+<alt>+i': on_activate_i}) as h:
    h.join()Release Notesv1.7.6 (2022-01-01) - Various fixesAllow passing virtual key codes to the parser for global hot keys.Stop the recording context asynchronously onXorg.Do not passNonetoobjc.objc_object. Thanks toyejunxi!Do not crash when pressing thealtkey onuinput. Thanks toCaldas
Lopes!Use the correct option prefix for listeners derived from the backend
implementations. Thanks toYu Wang!v1.7.5 (2021-11-19) - Various fixesCorrected crashes onXorgwhen a listener was configured to suppress
system events. Thanks tojpramosi!Improved handling of keyboard controller onWindows. The controller now
has a greater change of working with applications using lower level events.
Thanks tobhudax!UpdatedmacOSimplementation to use new version ofpyobjc.v1.7.4 (2021-10-10) - Various fixesDetect whether permissions are lacking onmacOS. Thanks toDane Finlay!Eagerly import symbols fromCoreFoundationandQuartz. Thanks toRonald Oussoren!Improved handling ofdumpkeysutility. Thanks toMarkus Niedermann!Removed ambiguous license file.v1.7.3 (2021-02-10) - Various fixesCorrectedkeysymhandling onXorg; not all groups were loaded, and the
fallback to our internal tables was never triggered. Thanks toPhilipp
Klaus!Updated the version ofQuartzused for themacOSbackend to allowpynputto be installed onBig Sur. Thanks toMichael Madden!Added missing function keys onWindows. Thanks toDave Atkinson!Corrected scroll speed for mouse controller onmacOS. Thanks toAlbert
Zeyer!Corrected media keys forXorg. Thanks toGabriele N. Tornetta!Corrected parameter name in documentation. Thanks toJinesi Yelizati!v1.7.2 (2020-12-21) - Corrected uinput key mappingCorrected mapping of virtual key codes to characters for theuinputbackend.Corrected spelling errors. Thanks toMartin Michlmayr!Corrected and improved documentation.v1.7.1 (2020-08-30) - Corrected release notesCorrected thanks for arbitrary unicode character support forXorg.v1.7.0 (2020-08-30) - A new backend and many new features and bug fixesAdded a newuinputbased keyboard backend forLinux, when noXserver
is available.Allow typing arbitrary unicode characters onXorgbackend. Thanks togdiShun!Allow overriding the automatically selected backend with an environment
variable, and added a dummy backend.Added support for mouse side button onWindows. Thanks todanielkovarik!Added convenience method to tap keys.Allow specifying raw virtual key codes in hotkeys.Improved error messages when a backend cannot be loaded.Include more information in stringification of events.Corrected return value ofEvents.getto that specified by the
documentation.Corrected keyboard listener not to type random characters on certain
keyboard layouts.Corrected errors when pressing certain keys onWindows, where the
operating system reports that they are dead but no combining version exists.Improved documentation.v1.6.8 (2020-02-28) - Various fixesUpdated documentation.Corrected lint warnings and tests.Do not use internal types inargtypesforwin32functions; this
renders them uncallable for other code running in the same runtime.Include scan codes in events onWindows. Thanks tobhudax!Correctly apply transformation to scroll event values onWindows. Thanks
toDOCCA0!v1.6.7 (2020-02-17) - Various fixesCorrected infinite scrolling onmacOSwhen providing non-integer deltas.
Thanks toIván Munsuri Ibáñez!Corrected controller and listener handling of media keys onmacOS. Thanks
toIván Munsuri Ibáñez!v1.6.6 (2020-01-23) - Corrected hot key documentationThe code examples for the simplepynput.keyboard.HotKeynow work. Thanks
tojfongattw!v1.6.5 (2020-01-08) - Corrected media key mappingsCorrected media key mappings onmacOS. Thanks toLuis Nachtigall!v1.6.4 (2020-01-03) - Corrected imports yet againCorrected imports for keyboard Controller. Thanks torhystedstone!v1.6.3 (2019-12-28) - Corrected imports againCorrected imports for keyboard Controller. Thanks toMatt Iversen!v1.6.2 (2019-12-28) - Corrected importsCorrected imports for keyboard Controller. Thanks toMatt Iversen!v1.6.1 (2019-12-27) - Corrections forWindowsCorrected global hotkeys onWindows.Corrected pressed / released state for keyboard listener onWindows.
Thanks tosegalion!v1.6.0 (2019-12-11) - Global HotkeysAdded support for global hotkeys.Added support for streaming listener events synchronously.v1.5.2 (2019-12-06) - Corrected media key names forXorgRemoved media flag fromXorgkeys.v1.5.1 (2019-12-06) - Corrected media key names formacOSCorrected attribute names for media keys onmacOS. Thanks toah3243!v1.5.0 (2019-12-04) - Various improvementsCorrected keyboard listener onWindows. Thanks toakiratakasaki,segalion,SpecialCharacter!Corrected handling of some special keys, including arrow keys, when combined
with modifiers onWindows. Thanks totuessetr!Updated documentation to include information about DPI scaling onWindows.
Thanks todavid-szarka!Added experimental support for media keys. Thanks toShivamJoker,StormTersteeg!v1.4.5 (2019-11-05) - Corrected errors onPython 3.8Corrected errors about usinginoperator for enums onPython 3.8onmacOS.v1.4.4 (2019-09-24) - Actually corrected keyboard listener on macOSIncluded commit to correctly fall back onCGEventKeyboardGetUnicodeString.Corrected deprecation warnings aboutEnumusage onPython 3.8.v1.4.3 (2019-09-24) - Corrected keyboard listener on macOS againCorrectly fall back onCGEventKeyboardGetUnicodeString.Updated documentation.v1.4.2 (2019-03-22) - Corrected keyboard listener on macOSUseCGEventKeyboardGetUnicodeStringinmacOSkeyboard listener to send
correct characters.Include keysym instead of key code inXorgkeyboard listener.Corrected logging to not include expectedStopException.Updated and corrected documentation.v1.4.1 (2018-09-07) - LoggingLog unhandled exceptions raised by listener callbacks.v1.4 (2018-07-03) - Event suppressionAdded possibility to fully suppress events when listening.Added support for typing some control characters.Added support for mouse drag events onOSX. Thanks tojungledrum!Include the key code in keyboard listener events.Correctly handle the numeric key pad onXorgwithnum lockactive.
Thanks toTheoRet!Corrected handling of current thread keyboard layout onWindows. Thanks toSchmettaling!Corrected stopping of listeners onXorg.Corrected import ofXlib.keysymdef.xkbonXorg. Thanks toGlandos!v1.3.10 (2018-02-05) - Do not crash underXephyrDo not crash whenXlib.display.Display.get_input_focusreturns an
integer, as it may when running underXephyr. Thanks toEli Skeggs!v1.3.9 (2018-01-12) - Correctly handle the letterAonOSXCorrected check for virtual key code when generating keyboard events onOSX. This fixes an issue where pressingAwithshiftexplicitly pressed
would still type a minuscule letter.v1.3.8 (2017-12-08) - Do not crash on some keyboard layouts onOSXFall back on a different method to retrieve the keyboard layout onOSX.
This helps for some keyboard layouts, such asChinese. Thanks tohaoflynet!v1.3.7 (2017-08-23) -XorgcorrectionsInclude mouse buttons up to30forXorg.v1.3.6 (2017-08-13) -win32correctionsCorrected double delivery of fake keyboard events onWindows.Corrected handling of synthetic unicode keys onWindows.v1.3.5 (2017-06-07) - Corrected dependencies againReverted changes in1.3.3.Corrected platform specifier forPython 2onLinux.v1.3.4 (2017-06-05) -XorgcorrectionsCorrected bounds check for values onXorg.v1.3.3 (2017-06-05) - Make dependencies non-optionalMade platform dependencies non-optional.v1.3.2 (2017-05-15) - Fix for button click on MacCorrected regression from previous release where button clicks would
crash theMacmouse listener.v1.3.1 (2017-05-12) - Fixes for unknown buttons on LinuxFall back onButton.unknownfor unknown mouse buttons inXorgmouse
listener.v1.3 (2017-04-10) - Platform specific featuresAdded ability to stop event propagation onWindows. This will prevent
events from reaching other applications.Added ability to ignore events onWindows. This is a workaround for systems
where the keyboard monitor interferes with normal keyboard events.Added ability to modify events onOSX. This allows intercepting and
altering input events before they reach other applications.Corrected crash onOSXwhen some types of third party input sources are
installed.v1.2 (2017-01-06) - Improved error handlingAllow 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 onLinux.Improved documentation.Thanks tojollyseanandgilleswijnkerfor their input!v1.1.7 (2017-01-02) - Handle middle button on WindowsListen for and dispatch middle button mouse clicks onWindows.v1.1.6 (2016-11-24) - Corrected context manager for pressing keysCorrected bug inpynput.keyboard.Controller.pressedwhich caused it to
never release the key. Many thanks to Toby Southwell!v1.1.5 (2016-11-17) - Corrected modifier key combinations on LinuxCorrected handling of modifier keys to allow them to be composable onLinux.v1.1.4 (2016-10-30) - Small bugfixesCorrected error generation whenGetKeyboardStatefails.Make sure to apply shift state to borrowed keys onX.Usepylint.v1.1.3 (2016-09-27) - Changed Xlib backend libraryChangedXliblibrary.v1.1.2 (2016-09-26) - Added missing type for Python 2Added missingLPDWORDforPython 2onWindows.v1.1.1 (2016-09-26) - Fixes for listeners and controllers on WindowsCorrected keyboard listener onWindows. Modifier keys and other keys
changing the state of the keyboard are now handled correctly.Corrected mouse click and release onWindows.Corrected code samples.v1.1 (2016-06-22) - Simplified usage on LinuxPropagate import errors raised on Linux to help troubleshoot missingXlibmodule.Declarepython3-xlibas dependency onLinuxforPython 3.v1.0.6 (2016-04-19) - Universal wheelMake sure to build a universal wheel for all python versions.v1.0.5 (2016-04-11) - Fixes for dragging on OSXCorrected dragging onOSX.Added scroll speed constant forOSXto correct slow scroll speed.v1.0.4 (2016-04-11) - Fixes for clicking and scrolling on WindowsCorrected name of mouse input field when sending click and scroll events.v1.0.3 (2016-04-05) - Fixes for Python 3 on WindowsCorrected use ofctypeson Windows.v1.0.2 (2016-04-03) - Fixes for thread identifiersUse thread identifiers to identify threads, not Thread instances.v1.0.1 (2016-04-03) - Fixes for Python 3Corrected bugs which prevented the library from being used onPython 3.v1.0 (2016-02-28) - Stable ReleaseChanged license toLGPL.Corrected minor bugs and inconsistencies.Corrected and extended documentation.v0.6 (2016-02-08) - Keyboard MonitorAdded support for monitoring the keyboard.Corrected wheel packaging.Corrected deadlock when stopping a listener in some cases onX.Corrected key code constants onMac OSX.Do not intercept events onMac OSX.v0.5.1 (2016-01-26) - Do not die on dead keysCorrected handling of dead keys.Corrected documentation.v0.5 (2016-01-18) - Keyboard ModifiersAdded support for modifiers.v0.4 (2015-12-22) - Keyboard ControllerAdded keyboard controller.v0.3 (2015-12-22) - CleanupMovedpynput.mouse.Controller.Buttonto top-level.v0.2 (2015-10-28) - Initial ReleaseSupport for controlling the mouse onLinux,Mac OSXandWindows.Support for monitoring the mouse onLinux,Mac OSXandWindows.