콘텐츠로 건너뛰기
Home » prompt toolkit을 사용하는 비동기 입력 프롬프트

prompt toolkit을 사용하는 비동기 입력 프롬프트

prompt_toolkit은 asyncio를 지원하는 prompt_async()를 제공한다. input() 함수나 보통의 prompt() 함수는 입력을 받는 중에는 스레드 전체를 블럭하기 때문에 다른 동작이 모두 멈추게 된다. prompt_async()는 이러한 문제를 해결할 수 있는 대안이다. 참고로 patch_stdout()을 사용하면 입력을 기다리는 중에 다른 코루틴이 출력을 할 수 있게 하면서, 입력 중간에 출력되는 내용 때문에 입력 프롬프트가 망가지는 것을 방지할 수 있다. (단 코루틴에서 print()를 통해 출력한 경우만 제대로 작동하는 것 같고, print_formatted_text()를 쓰면 좀 꼬이는 거 같긴 하다…)

import asyncio
from prompt_toolkit import PromptSession
from prompt_toolkit.patch_stdout import patch_stdout


# 출력
async def task1():
  while True:
    print('prompt toolkit is awesome.')
    await asyncio.sleep(1)


# 입력!
async def task2():
  session = PromptSession()
  while True:
    with patch_stdout():
      line = await session.prompt_async('> ')
    print(line)
asyncio.run(asyncio.wait((task1(), task2())))

위 코드에서 task1은 1초마다 화면에 문구를 반복해서 출력한다. task2에서는 Prompt Session을 사용하면서 prompt_async()를 사용해서 입력을 받는다. 이 덕분에 입력 프롬프트가 스레드를 블럭하지 않아서 출력 작업은 방해받지 않고 일어나는 것을 볼 수 있으며, 글자를 입력하는 중에 다른 코루틴이 문자를 출력하게되더라도 입력 프롬프트가 잽싸게(?) 다시 그려지면서 입력 내용이 중간에 깨지는 것을 막아주는 것을 볼 수 있다.