[Python] How to use prompt-toolkit key binding with inner prompt

Discussão em 'Python' iniciado por Stack, Março 17, 2025.

  1. Stack

    Stack Membro Participativo

    I have a prompt_toolkit application where I want a bunch of keys to be acted on immediately, without pressing Enter. It's not a fullscreen app, it's just using the bottom_toolbar. So I have set up key bindings:

    class Annotator:
    def process(self):
    kb = KeyBindings()

    @kb.add("5")
    def _(event):
    self.buildJohnnyFive()

    @kb.add("s")
    def _(event):
    self.needInput()

    text = prompt("> ", bottom_toolbar=self.bottomToolbar, key_bindings=kb)
    print(f"You said: {text}")

    def buildJohnnyFive(self):
    self.buildHim() # Do work

    def needInput(self):
    raw = prompt("input> ", bottom_toolbar=self.bottomToolbar)
    self.useInput(raw)

    def bottomToolbar(self):
    return f"Current: {self.status1} - {self.status2}"


    This works well, and the functions get called. However, in some of these functions I need to accept more specific input from the user. But when I call prompt() from inside the function bound to a key, I get an exception:

    File "/opt/homebrew/Cellar/python@3.10/3.10.13_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 714, in read_from_input_in_context
    context.copy().run(read_from_input)
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 694, in read_from_input
    self.key_processor.process_keys()
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/key_binding/key_processor.py", line 273, in process_keys
    self._process_coroutine.send(key_press)
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/key_binding/key_processor.py", line 188, in _process
    self._call_handler(matches[-1], key_sequence=buffer[:])
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/key_binding/key_processor.py", line 323, in _call_handler
    handler.call(event)
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/key_binding/key_bindings.py", line 127, in call
    result = self.handler(event)
    File "/Users/nick/my_app/src/annotator.py", line 110, in _
    self.addCustomED()
    File "/Users/nick/my_app/src/annotator.py", line 145, in needInput
    raw = prompt("input> ", bottom_toolbar=self.bottom_toolbar)
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1425, in prompt
    return session.prompt(
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1035, in prompt
    return self.app.run(
    File "/Users/nick/my_app/.venv/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 1002, in run
    return asyncio.run(coro)
    File "/opt/homebrew/Cellar/python@3.10/3.10.13_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 33, in run
    raise RuntimeError(

    Exception asyncio.run() cannot be called from a running event loop


    I understand the problem: I'm already running a prompt(), which hasn't ended yet, and now I'm asking for another, inner prompt which conflicts with the existing event loop.

    What I don't understand is: how am I supposed to do this? I need to call the initial prompt so that the user gets the info in the bottom toolbar. There needs to be a run loop so that the app doesn't quit before the user has time to press keys. But then how am I supposed to get input at this inner function? Can I somehow end or suspend the outer prompt while the inner prompt is waiting for the user's input? I don't want to switch to doing everything on the one prompt, because then the user will have to press Return every time. And I actually don't WANT the terminal to fill up with lines of input commands.

    Some guidance would be much appreciated.

    Continue reading...

Compartilhe esta Página