¿Cómo tener una línea de entrada cómoda (por ejemplo, al estilo del GNU-readline) en una tarea de asyncio?
Tengo un programa asyncio con dos tareas:
- la tarea 1 realiza cierto trabajo
- la tarea 2 proporciona una interfaz de línea de comandos (CLI); lee comandos escritos por el usuario y los envía a la tarea 1 para que los procese
La CLI es básicamente un bucle que lee líneas de un flujo asyncio conectado a la entrada estándar.
Funciona, pero no es muy cómodo. El problema es que la línea de entrada no ofrece comandos de edición, excepto [BACKSPACE ctrl-H] y [ctrl-U], que se procesan a nivel de terminal de Linux, no en el programa. Quiero al menos flechas [LEFT] y [RIGHT] y [DEL].
Intenté usar la función interna input()
con readline
importado, lo que me da una edición cómoda, pero debe ejecutarse en un thread separado porque es bloqueante (loop.run_in_executor
).
Ahora el problema es el manejo de [ctrl-C] (KeyboardInterrupt
). Las tareas se cancelan, pero input()
en su propio thread todavía espera la tecla [ENTER]. Solo después de presionar [ENTER], la aplicación se detiene. Esto es tan confuso y es un “bloqueador de errores” para este enfoque. Desafortunadamente, no es posible matar un thread, así que no puedo hacer que una pulsación de tecla [ctrl-C] termine el programa de forma normal.
¿Tienes alguna idea de cómo resolver el problema con input()
o conoces una forma alternativa de habilitar la edición básica de la línea de entrada en una tarea asyncio?
davy.ai
Para habilitar la edición básica de líneas de entrada en una tarea asyncio, una solución es utilizar la biblioteca
prompt_toolkit
, que proporciona una manera de construir interfaces de línea de comandos con capacidades de edición avanzadas.Esta biblioteca se integra bien con asyncio y proporciona una implementación de ciclo de eventos
asyncio
. Conprompt_toolkit
, puede obtener características avanzadas de edición, como autocompletado, resaltado de sintaxis, entrada de varias líneas, historial y deshacer-rehacer.Aquí hay un ejemplo de cómo puede usar
prompt_toolkit
para habilitar la edición básica de líneas de entrada:En este ejemplo, creamos un objeto
PromptSession
que podemos usar para leer la entrada del usuario conprompt_async
. La funciónprompt_async
nos permite leer la entrada de forma asíncrona y proporciona una corrutina que podemos esperar.prompt_async
nos proporciona capacidades básicas de edición, como flechas Izquierda/Derecha y Borrar.Con este enfoque, también puede manejar
KeyboardInterrupt
y detener el ciclo de manera ordenada.¡Espero que esto ayude!