14

I am writing a script to automate running a particular model. When the model fails, it waits for a user input (Enter key). I can detect when the model has failed, but I am not able to use python (on linux) to simulate a key press event. Windows has the SendKeys library to do this but I was wondering if there is a similar library for python on linux.

Thanks!

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
user308827
  • 21,227
  • 87
  • 254
  • 417

6 Answers6

15

Have a look at this https://github.com/SavinaRoja/PyUserInput its cross-platform control for mouse and keyboard in python

Keyboard control works on X11(linux) and Windows systems. But no mac support(when i wrote this answer).

from pykeyboard import PyKeyboard
k = PyKeyboard()

# To Create an Alt+Tab combo
k.press_key(k.alt_key)
k.tap_key(k.tab_key)
k.release_key(k.alt_key)
naren
  • 14,611
  • 5
  • 38
  • 45
  • Do you know how to 'tap' the space key? – user3768495 Jul 01 '15 at 22:40
  • Take a look at these projs, space key must be mapped to ' '(string with space in it) https://github.com/Narengowda/web-mouse/blob/master/web_mouse/mouse_wsh.py#L62 https://github.com/SavinaRoja/PyUserInput/blob/master/pykeyboard/x11.py#L28 – naren Jul 02 '15 at 10:19
  • I came up with something like `k.tab_key(k.keypad_keys['Space'])` but it doesn't work. It is hard for me to understand the project documentation. Could you please help? – user3768495 Jul 02 '15 at 16:23
  • Did you try key_board.type_string(' ') ? – naren Jul 03 '15 at 08:16
10

A more low-level approach would be to create an uinput device from which you would then inject input events into the linux input subsystem. Consider the following libraries:

Example of sending <enter> with the latter:

from evdev import uinput, ecodes as e

with uinput.UInput() as ui:
     ui.write(e.EV_KEY, e.KEY_ENTER, 1)
     ui.write(e.EV_KEY, e.KEY_ENTER, 0)
     ui.syn()
Pixelmonster
  • 396
  • 7
  • 15
gvalkov
  • 3,977
  • 30
  • 31
7

If the "model" is running graphically (with the X window system), the already-suggested xsendkey is a possibility, or xsendkeycode. If it's running textually (in a terminal window), then pexpect.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Hi! A corollary: While using pexpect, the following simple program doesn't seem to work for me: import pexpect child = pexpect.spawn('ls') fout = file('output.txt', 'w') child.logfile = fout I.e, output.txt is created but is empty when I cat it. pexpect is installed fine, since I can run the samples supplied with the program. Any suggestions would be appreciated! thanks! – user308827 Apr 05 '10 at 21:14
  • 9
    The links to `xsendkey` and `xsendkeycode` are dead. – hazzey Jan 05 '15 at 02:10
  • @hazzey here is a fork that works great: https://github.com/kyoto/sendkeys The xsendkey program is awesome to bypass restrictions when a simple copy-paste is not allowed and when you have to write tags followed by a validation with the enter / return key, like on Tumblr (a JavaScript hack would have been more complicated) – baptx Sep 25 '16 at 17:10
2

I recommend PyAutoGui. It's ridiculously simple to use, it's cross-platform and it's for Python 3 and 2.

In the linked page are listed the dependences and some code examples.

Marco Sulla
  • 15,299
  • 14
  • 65
  • 100
1

http://people.csail.mit.edu/adonovan/hacks/xsendkey.html

baol
  • 4,362
  • 34
  • 44
  • 1
    You can obviously take a look at the rather simple code of xsendkey and search for the corresponding calls in the Xlib binding for python. – baol Apr 04 '10 at 22:45
0

As many of the solutions I have found in this and in another well ranked SO response were either deprecated (PyUserInput) or using evdev, which failed (UInputError: "/dev/uinput" cannot be opened for writing) the simplest solution for me using Linux was pynput. One example directly from their docs:

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')

It worked like a charm!

Eduardo
  • 4,282
  • 2
  • 49
  • 63