Package: terminable
terminablePython library for cross-platform terminal input.Tested onWindows,macOS, andLinuxDoes not require root accessProvideskeyboard,mouse, andterminal-resizeeventsSimple APIthat you can plug intoyour own event loopDoes not require a full-screen terminal appor separate windowInstallpython3 -m pip install terminableUsageimportterminablewithterminable.capture_input()asterminal_input:whileTrue:returned_value=terminal_input.read()print(f"Input received:{returned_value}\r")Sample output:Input received: KeyEvent(Char(a), KeyModifiers.NONE)
Input received: KeyEvent(Char(s), KeyModifiers.NONE)
Input received: KeyEvent(Char(A), KeyModifiers.SHIFT)
Input received: KeyEvent(Char(S), KeyModifiers.SHIFT)
Input received: KeyEvent(Char(F), KeyModifiers.SHIFT)
Input received: KeyEvent(Key.F1, KeyModifiers.NONE)
Input received: KeyEvent(Key.F3, KeyModifiers.NONE)
Input received: KeyEvent(Key.F2, KeyModifiers.NONE)
Input received: KeyEvent(Char(l), KeyModifiers.CONTROL)
Input received: KeyEvent(Char(k), KeyModifiers.CONTROL)
Input received: KeyEvent(Char(p), KeyModifiers.CONTROL)
Input received: MouseEvent(MouseEventKind.MOVED, None, 54, 20, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.MOVED, None, 53, 20, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.MOVED, None, 52, 20, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.MOVED, None, 51, 20, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.MOVED, None, 54, 19, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.SCROLL_DOWN, None, 54, 19, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.SCROLL_DOWN, None, 54, 19, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.SCROLL_DOWN, None, 54, 19, KeyModifiers.NONE)
Input received: MouseEvent(MouseEventKind.SCROLL_DOWN, None, 54, 19, KeyModifiers.NONE)
Input received: ResizeEvent(104, 31)
Input received: ResizeEvent(100, 31)
Input received: ResizeEvent(98, 31)
Input received: ResizeEvent(95, 31)Types of inputKeyboardCharactersArrow keysFunction keysEnter, Esc, Backspace, etc.Modifiers:CONTROL,SHIFT,ALT, etc.MouseMoveDownUpDragScroll (scroll wheel, trackpad scroll gestures)Resizeof terminal windowImplementationterminableis a thin Python wrapper around the excellentcrosstermRust library.crosstermdoes all the heavy lifting.terminableexposes a small subset ofcrosstermfunctionality to Python usingPyO3.APIcapture_inputterminablehas a single function:defcapture_input()->InputCapture:...InputCaptureTheInputCaptureobject is a context manager object (intended to be used with Python'swithstatement).When theInputCaptureobject is created, the terminal is placed intoraw mode, such that:Input is not automatically echoedprintcalls do not automatically add a carriage return (\r)Control sequences are not automatically processedWhen theInputCaptureobject is destroyed, the terminal exits raw mode.readInputCapturehas a single function:def read(self) -> KeyEvent | MouseEvent | ResizeEvent:
    ...readblocks until input is received.Ctrl+Cterminableraises aKeyboardInterruptexception onCtrl+C.Comparison with other librariesThere are other existing libraries for getting terminal input in Python, but each of them have their limitations:cursesis not supported on Windows and requires a the terminal app to be full screentermiosis not supported on WindowsUniCursesis a cross-platform implementation ofcurses, but it is no longer maintained andusers have reported issues on Windowspygameprovides comprehensive input functionality, but it requires a separate graphical window and isnot well-suited for terminal inputkeyboardrequires root accesson some platformspynputrequires root accesson some platformstextualhas good cross-platform input handling in a terminal app, but it is tightly coupled with thetextualapplication model; you have to lettextualrun your event loop, for example.blessedhas excellent cross-platformkeyboardinput functionality that is easy to use in your own event loop, butblesseddoes not supportmouseinput.