"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Cómo crear un chat interactivo para su CLI de Python mediante introspección, clics y formato enriquecido

Cómo crear un chat interactivo para su CLI de Python mediante introspección, clics y formato enriquecido

Publicado el 2024-11-08
Navegar:948

How to Build an Interactive Chat for Your Python CLI Using Introspection, Click, and Rich Formatting

Si alguna vez quiso que su CLI fuera más interactiva y dinámica, crear un sistema de interacción de comandos en tiempo real podría ser la respuesta. Al aprovechar las capacidades de introspección de Python, Click para administrar comandos y Rich para formatear la salida, puede crear una CLI potente y flexible que responda de manera inteligente a las entradas del usuario. En lugar de codificar manualmente cada comando, su CLI puede descubrir y ejecutar comandos automáticamente, lo que hace que la experiencia del usuario sea más fluida y atractiva.

Caos colorido en la consola: donde los comandos Click se encuentran con resultados enriquecidos, ¡porque incluso al terminal le gusta lucirse con estilo!

¿Por qué utilizar Click y Markdown?

Click simplifica la gestión de comandos, el análisis de argumentos y la generación de ayuda. También permite una fácil estructuración de comandos y manejo de opciones.

Rich le permite generar Markdown bellamente formateado directamente en la terminal, lo que hace que los resultados no solo sean funcionales sino también visualmente atractivos.

Al combinar estas dos bibliotecas con la introspección de Python, puede crear una función de chat interactivo que descubre y ejecuta comandos dinámicamente mientras muestra la salida en un formato rico y legible. Para ver un ejemplo práctico, vea cómo StoryCraftr utiliza un enfoque similar para optimizar los flujos de trabajo de escritura impulsados ​​por IA: https://storycraftr.app.

Construyendo el sistema de chat interactivo

1. Configurar el comando de chat básico

El comando de chat inicializa la sesión, lo que permite a los usuarios interactuar con la CLI. Aquí, capturamos la entrada del usuario, que se asignará dinámicamente a los comandos Click apropiados.

import os
import click
import shlex
from rich.console import Console
from rich.markdown import Markdown

console = Console()

@click.command()
@click.option("--project-path", type=click.Path(), help="Path to the project directory")
def chat(project_path=None):
    """
    Start a chat session with the assistant for the given project.
    """
    if not project_path:
        project_path = os.getcwd()

    console.print(
        f"Starting chat for [bold]{project_path}[/bold]. Type [bold green]exit()[/bold green] to quit."
    )

    # Start the interactive session
    while True:
        user_input = console.input("[bold blue]You:[/bold blue] ")

        # Handle exit
        if user_input.lower() == "exit()":
            console.print("[bold red]Exiting chat...[/bold red]")
            break

        # Call the function to handle command execution
        execute_cli_command(user_input)

2. Introspección para descubrir y ejecutar comandos

Utilizando la introspección de Python, descubrimos dinámicamente los comandos disponibles y los ejecutamos. Una parte crucial aquí es que los comandos Click son funciones decoradas. Para ejecutar la lógica real, necesitamos llamar a la función no decorada (es decir, la devolución de llamada).

Así es como puedes ejecutar comandos dinámicamente usando la introspección y manejar los decoradores de Click:

import inspect
import your_project_cmd  # Replace with your actual module containing commands

command_modules = {"project": your_project_cmd}  # List your command modules here

def execute_cli_command(user_input):
    """
    Function to execute CLI commands dynamically based on the available modules,
    calling the undecorated function directly.
    """
    try:
        # Use shlex.split to handle quotes and separate arguments correctly
        parts = shlex.split(user_input)
        module_name = parts[0]
        command_name = parts[1].replace("-", "_")  # Replace hyphens with underscores
        command_args = parts[2:]  # Keep the rest of the arguments as a list

        # Check if the module exists in command_modules
        if module_name in command_modules:
            module = command_modules[module_name]

            # Introspection: Get the function by name
            if hasattr(module, command_name):
                cmd_func = getattr(module, command_name)

                # Check if it's a Click command and strip the decorator
                if hasattr(cmd_func, "callback"):
                    # Call the underlying undecorated function
                    cmd_func = cmd_func.callback

                # Check if it's a callable (function)
                if callable(cmd_func):
                    console.print(
                        f"Executing command from module: [bold]{module_name}[/bold]"
                    )

                    # Directly call the function with the argument list
                    cmd_func(*command_args)
                else:
                    console.print(
                        f"[bold red]'{command_name}' is not a valid command[/bold red]"
                    )
            else:
                console.print(
                    f"[bold red]Command '{command_name}' not found in {module_name}[/bold red]"
                )
        else:
            console.print(f"[bold red]Module {module_name} not found[/bold red]")
    except Exception as e:
        console.print(f"[bold red]Error executing command: {str(e)}[/bold red]")

¿Cómo funciona esto?

  • Análisis de entrada: Usamos shlex.split para manejar la entrada como argumentos de línea de comandos. Esto garantiza que las cadenas entrecomilladas y los caracteres especiales se procesen correctamente.
  • Búsqueda de módulos y comandos: la entrada se divide en nombre_módulo y nombre_comando. El nombre del comando se procesa para reemplazar los guiones con guiones bajos para que coincidan con los nombres de las funciones de Python.
  • Introspección: Usamos getattr() para recuperar dinámicamente la función de comando del módulo. Si es un comando Click (es decir, tiene el atributo de devolución de llamada), accedemos a la lógica de la función real eliminando el decorador Click.
  • Ejecución de comando: Una vez que recuperamos la función no decorada, pasamos los argumentos y la llamamos, como si estuviéramos invocando directamente una función de Python.

3. Ejemplos de comandos CLI

Consideremos algunos comandos de muestra dentro de un módulo de proyecto que los usuarios pueden llamar de forma interactiva a través del chat:

@click.group()
def project():
    """Project management CLI."""
    pass

@project.command()
def init():
    """Initialize a new project."""
    console.print("[bold green]Project initialized![/bold green]")

@project.command()
@click.argument("name")
def create(name):
    """Create a new component in the project."""
    console.print(f"[bold cyan]Component {name} created.[/bold cyan]")

@project.command()
def status():
    """Check the project status."""
    console.print("[bold yellow]All systems operational.[/bold yellow]")

Ejecutando la interfaz de chat

Para ejecutar el sistema de chat interactivo:

  1. Asegúrate de que tus módulos (como el proyecto) estén listados en command_modules.
  2. Ejecute el comando:
python your_cli.py chat --project-path /path/to/project

Una vez que comienza la sesión, los usuarios pueden ingresar comandos como:

You: project init You: project create "Homepage"

La salida se mostrará en un formato correcto utilizando Rich Markdown:

[bold green]Project initialized![/bold green] [bold cyan]Component Homepage created.[/bold cyan]

Conclusión

Al combinar Click para la administración de comandos, Rich para el formato Markdown y la introspección de Python, podemos crear un sistema de chat potente e interactivo para CLI. Este enfoque le permite descubrir y ejecutar comandos dinámicamente mientras presenta el resultado en un formato elegante y legible.

Aspectos destacados:

  • Ejecución dinámica de comandos: la introspección le permite descubrir y ejecutar comandos sin codificarlos.
  • Resultado enriquecido: el uso de Rich Markdown garantiza que el resultado sea fácil de leer y visualmente atractivo.
  • Flexibilidad: Esta configuración permite flexibilidad en la estructura y ejecución de los comandos.
Declaración de liberación Este artículo se reproduce en: https://dev.to/rodrigo_estrada_79e6022e9/how-to-build-an-interactive-chat-for-your-python-cli-using-introspection-click-and-rich-formatting-4l9a? 1 como Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3