"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como construir um bate-papo interativo para sua CLI Python usando introspecção, clique e formatação avançada

Como construir um bate-papo interativo para sua CLI Python usando introspecção, clique e formatação avançada

Publicado em 2024-11-08
Navegar:694

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

Se você sempre quis tornar sua CLI mais interativa e dinâmica, construir um sistema de interação de comando em tempo real pode ser a resposta. Ao aproveitar os recursos de introspecção do Python, Click para gerenciar comandos e Rich para formatar a saída, você pode criar uma CLI poderosa e flexível que responde de forma inteligente à entrada do usuário. Em vez de codificar manualmente cada comando, sua CLI pode descobrir e executar comandos automaticamente, tornando a experiência do usuário mais suave e envolvente.

Caos colorido do console: onde os comandos Click encontram a saída rica - porque até o terminal gosta de se exibir com estilo!

Por que usar Click e Markdown?

Click simplifica o gerenciamento de comandos, análise de argumentos e geração de ajuda. Ele também permite fácil estruturação de comandos e manipulação de opções.

Rich permite que você produza Markdown lindamente formatado diretamente no terminal, tornando os resultados não apenas funcionais, mas também visualmente atraentes.

Ao combinar essas duas bibliotecas com a introspecção Python, você pode construir um recurso de bate-papo interativo que descobre e executa comandos dinamicamente enquanto exibe a saída em um formato rico e legível. Para obter um exemplo prático, veja como StoryCraftr usa uma abordagem semelhante para agilizar fluxos de trabalho de escrita orientados por IA: https://storycraftr.app.

Construindo o Sistema de Chat Interativo

1. Configurando o comando básico de bate-papo

O comando chat inicializa a sessão, permitindo que os usuários interajam com a CLI. Aqui, capturamos a entrada do usuário, que será mapeada dinamicamente para os comandos Click apropriados.

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. Introspecção para descobrir e executar comandos

Usando a introspecção Python, descobrimos dinamicamente os comandos disponíveis e os executamos. Uma parte crucial aqui é que os comandos Click são funções decoradas. Para executar a lógica real, precisamos chamar a função não decorada (ou seja, o retorno de chamada).

Veja como você pode executar comandos dinamicamente usando introspecção e lidar com os decoradores do 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]")

Como é que isso funciona?

  • Análise de entrada: usamos shlex.split para lidar com entradas como argumentos de linha de comando. Isso garante que as strings entre aspas e os caracteres especiais sejam processados ​​corretamente.
  • Module and Command Lookup: A entrada é dividida em module_name e command_name. O nome do comando é processado para substituir hífens por sublinhados para corresponder aos nomes das funções Python.
  • Introspecção: Usamos getattr() para buscar dinamicamente a função de comando do módulo. Se for um comando Click (ou seja, tiver o atributo callback), acessamos a lógica da função real removendo o decorador Click.
  • Execução de comando: Depois de recuperarmos a função não decorada, passamos os argumentos e a chamamos, como se estivéssemos invocando diretamente uma função Python.

3. Exemplos de comandos CLI

Vamos considerar alguns exemplos de comandos dentro de um módulo de projeto que os usuários podem chamar interativamente por meio do 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]")

Executando a interface de bate-papo

Para executar o sistema de chat interativo:

  1. Certifique-se de que seus módulos (como projeto) estejam listados em command_modules.
  2. Execute o comando:
python your_cli.py chat --project-path /path/to/project

Assim que a sessão for iniciada, os usuários poderão inserir comandos como:

You: project init You: project create "Homepage"

A saída será exibida de maneira bem formatada usando Rich Markdown:

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

Conclusão

Ao combinar Click para gerenciamento de comandos, Rich para formatação Markdown e introspecção Python, podemos construir um sistema de bate-papo poderoso e interativo para CLIs. Essa abordagem permite descobrir e executar comandos dinamicamente enquanto apresenta a saída em um formato elegante e legível.

Principais destaques:

  • Execução dinâmica de comandos: a introspecção permite que você descubra e execute comandos sem codificá-los.
  • Rich Output: Usar Rich Markdown garante que a saída seja fácil de ler e visualmente atraente.
  • Flexibilidade: Esta configuração permite flexibilidade na estrutura e execução de comandos.
Declaração de lançamento Este artigo está reproduzido em: https://dev.to/rodrigo_estrada_79e6022e9/how-to-build-an-interactive-chat-for-your-python-cli-using-introspection-click-and-rich-formatting-4l9a? 1, pois se houver alguma violação, entre em contato com [email protected] para excluí-la.
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3