jquast / blessed

Blessed is an easy, practical library for making python terminal apps
http://pypi.python.org/pypi/blessed
MIT License
1.2k stars 71 forks source link

asyncio support #154

Open jquast opened 4 years ago

jquast commented 4 years ago

Maybe we can be of help, here.

Propose:

haliphax commented 4 years ago

This would be awesome! My shim is good enough for what I'm building, but I would love to have asyncio supported further upstream in blessed itself. Cheers.

wagnerflo commented 3 years ago

Since I could use asyncio support in blessed for a future project of mine, I'm willing to tackle this, provided there is still interest in including this in the library and provided I get a bit of input and help on the design decisions that follow.

avylove commented 3 years ago

I think any help would be appreciated, though I can't guarantee how quickly we'll be able to respond to PRs.

da-h commented 3 years ago

Hey,

I've got an easy workaround for an asyncio-compatible inkey. The idea is to run inkey in a seperate Thread and pass the result to a asyncio.Queue.

The example script waits for a user-input in a asyncio-loop. To show that it is non-blocking, the script timeouts the query with a message.

import asyncio
import threading
from asyncio import Queue
from blessed import Terminal

queue = Queue()
term = Terminal()

def threaded_inkey():
    running = True
    with term.cbreak():
        while running:
            key = term.inkey()
            if key == "q":
                running = False
            queue.put_nowait(key)
            queue._loop._write_to_self()

async def mainloop():
    running = True
    with term.fullscreen():
        print("press a key. (exit using 'q')")
        while running:
            try:
                key = await asyncio.wait_for(queue.get(), 1)
                if key == "q":
                    running = False
                print("key pressed:", key)
            except asyncio.TimeoutError:
                print("no key pressed")

loop = asyncio.get_event_loop()
threading.Thread(target=threaded_inkey).start()
loop.run_until_complete(mainloop())

Do you want me to add a PR to add this to the documentation?

Best, da-h

haolian9 commented 3 years ago

as asyncio has been considered, is there enough room for trio?

--- update

maybe an useful reference: starlette has supported trio via anyio

--- update i created a gist that implements inkey in trio

wagnerflo commented 3 years ago

Since I've recently started playing around with trio and I like it a bit better even than asyncio, my current plan was to have a look if this is easily doable using anyio. It's on my ToDo list and since this is relevant for a project at work I'll get to it at one point for sure, but currently can't promise a timeline.

jquast commented 3 years ago

Thank you @wagnerflo, @da-h, and @haolian9 for your initiative to add asyncio support to blessed. I'm glad to see there is some interest here. I forgot to link @haliphax's inkey() implementation, which I think is very nice, please review https://github.com/haliphax/xthulu/blob/master/xthulu/terminal.py#L170-L227

Just a reminder that for this change to be accepted it will need,