prompt-toolkit / prompt-toolkit/python-prompt-toolkit

Accept input from user and also programmatically pipe input from background thread

Open
#1,526 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
10.6k
Forks
815
PR merge metrics
No merged PRs in 30d

Description

I am trying to create an IPython application that will by default wait for user input on the shell.
In addition, I would like to programmatically issue commands on the terminal via a background thread when certain events happen.

In the unit testing section of the docs, I came across create_pipe_input and create_app_session functions. From my understanding, it seems to me that create_app_session is useful for binding input and/or output objects to the Application at creation time.
However, I would like to do one of the following

  • Have 2 input objects on the Application
    OR
  • Hot-swap between the default input object and the pipe input and perform 'rebinding' of the input and output

I tried doing the following in the background thread, hot-swapping as well as the app session ctx manager. However, both approaches didn't help me achieve what I was looking for

import time
from threading import Thread

from prompt_toolkit.input import create_pipe_input
from prompt_toolkit.application.current import create_app_session
from IPython.terminal.interactiveshell import TerminalInteractiveShell
from IPython.terminal.embed import InteractiveShellEmbed

ip_shell = InteractiveShellEmbed()


def auto_input():

    time.sleep(2)

    s: TerminalInteractiveShell = get_ipython()
    pipe_input = create_pipe_input()

    # -----------------------------------------------
    # Try hot-swapping the input object 
    # -----------------------------------------------
    orig_input = s.pt_app.app.input
    s.pt_app.app.input = pipe_input
    s.pt_app.app.invalidate()
    pipe_input.send_text('print("Hello. This is an automatic input...")')
    s.pt_app.app.input = orig_input

    # -----------------------------------------------
    # Try using the AppSession contxt manager
    # -----------------------------------------------
    with create_app_session(input=pipe_input):
        pipe_input.send_text('print("Hello. This is an automatic input...")\r')


ip_thread = Thread(name="Auto input thread", target=auto_input)
ip_thread.start()

ip_shell()

ip_thread.join()

Can someone please provide some pointers on what I can do to accept input from the user and also programmatically pipe input from a background thread?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the unit testing documentation and the implementations of create_pipe_input and create_app_session. Then trace how Application binds and reads its input while TerminalInteractiveShell and InteractiveShellEmbed are active. Done should be a documented or supported way to accept terminal input while safely submitting programmatic input from a background thread.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.