Get asynchronous input from console in Python

Question:

I am making a Python program that, when running, can receive input from the terminal.

For example, while a process is running, it can be controlled asynchronously from the terminal and not pause for user input.

How do I do this in Python?

Answer:

import asyncio
import sys
import os

startstop = asyncio.Event()

async def main():
    print('wait start')
    await startstop.wait()
    while startstop.is_set():
        print('.',end='',flush=True)
        await asyncio.sleep(1)

def reader_cb(infile, task):
    cmd = infile.readline().strip()
    print(repr(cmd))
    if cmd == 'start':
        startstop.set()
    elif cmd == 'stop':
        startstop.clear()
    elif cmd == 'kill':
        startstop.clear()
        task.cancel()

loop=asyncio.get_event_loop()
# task = loop.create_task(main())
loop.add_reader(sys.stdin.fileno(), reader_cb, sys.stdin, task)
# loop.run_forever()
asyncio.run(main())

On Windows select is not able not on sockets. https://docs.python.org/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop

Switch to ProactorEventLoop before the main code.

import asyncio, sys

if sys.platform == 'win32':
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)

And although we read on …

add_reader () and add_writer () are not supported

Try uvloop:

$ pip install uvloop

import asyncio
import uvloop
uvloop.install()

async def main():
    # Main entry-point.
    ...
...
asyncio.run(main())
Scroll to Top