I'd like to make a program in Python that works a bit like fzf - you pipe input, manipulate it, and it's piped to something else.
I have tried making a program like this in Python using urwid. If I set up a fake input within the program, it works the way I want it to, but if I pipe input (cat foo.txt | python myprog.py) I get an error. How can I make this work?
In particular, I would like to be able to start the UI before closing stdin, the same as fzf.
To give a simple example of the issue I ran into, given this program:
import urwid
txt = urwid.Text("blah")
filler = urwid.Filler(txt)
def quitter(key):
if key == "q":
raise urwid.ExitMainLoop()
loop = urwid.MainLoop(filler, unhandled_input=quitter)
loop.run()
This command line:
ls | python script.py
Gives this error:
TypeError: ord() expected a character, but string of length 0 found
It wasn't obvious to me why this would happen, but looking at this issue for example, it does seem to be related to piping input.
It looks like the way to do this is to create a
Screenthat uses the tty, rather than stdin, as input. This screen object must then be passed to the main loop. Example:This old mailing list post got me partway there.