Comment créer une discussion interactive pour votre CLI Python à l'aide de l'introspection, du clic et du formatage enrichi

Barbara Streisand
Libérer: 2024-10-26 11:00:29
original
831 Les gens l'ont consulté

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

Si vous avez toujours voulu rendre votre CLI plus interactive et dynamique, la création d'un système d'interaction de commandes en temps réel pourrait être la réponse. En tirant parti des capacités d'introspection de Python, de Click pour gérer les commandes et de Rich pour formater la sortie, vous pouvez créer une CLI puissante et flexible qui répond intelligemment aux entrées de l'utilisateur. Au lieu de coder manuellement en dur chaque commande, votre CLI peut découvrir et exécuter automatiquement des commandes, rendant l'expérience utilisateur plus fluide et plus attrayante.

Chaos de consoles colorées : où les commandes Click rencontrent des résultats riches, car même le terminal aime se montrer avec style !

Pourquoi utiliser Click and Markdown ?

Click simplifie la gestion des commandes, l'analyse des arguments et la génération d'aide. Il permet également une structuration facile des commandes et une gestion des options.

Rich vous permet de produire du Markdown magnifiquement formaté directement dans le terminal, ce qui rend les résultats non seulement fonctionnels mais aussi visuellement attrayants.

En combinant ces deux bibliothèques avec l'introspection Python, vous pouvez créer une fonctionnalité de discussion interactive qui découvre et exécute dynamiquement des commandes tout en affichant le résultat dans un format riche et lisible. Pour un exemple pratique, découvrez comment StoryCraftr utilise une approche similaire pour rationaliser les flux de travail d'écriture basés sur l'IA : https://storycraftr.app.

Construire le système de chat interactif

1. Configuration de la commande de discussion de base

La commande chat initialise la session, permettant aux utilisateurs d'interagir avec la CLI. Ici, nous capturons les entrées de l'utilisateur, qui seront mappées dynamiquement aux commandes Click appropriées.

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)
Copier après la connexion
Copier après la connexion

2. Introspection pour découvrir et exécuter des commandes

Grâce à l'introspection Python, nous découvrons dynamiquement les commandes disponibles et les exécutons. Un élément crucial ici est que les commandes Click sont des fonctions décorées. Pour exécuter la logique réelle, nous devons appeler la fonction non décorée (c'est-à-dire le rappel).

Voici comment exécuter dynamiquement des commandes en utilisant l'introspection et gérer les décorateurs de Click :

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)
Copier après la connexion
Copier après la connexion

Comment cela marche-t-il?

  • Analyse des entrées : Nous utilisons shlex.split pour gérer les entrées telles que les arguments de ligne de commande. Cela garantit que les chaînes entre guillemets et les caractères spéciaux sont traités correctement.
  • Recherche de module et de commande : l'entrée est divisée en nom_module et nom_commande. Le nom de la commande est traité pour remplacer les traits d'union par des traits de soulignement afin de correspondre aux noms de fonctions Python.
  • Introspection : Nous utilisons getattr() pour récupérer dynamiquement la fonction de commande du module. S'il s'agit d'une commande Click (c'est-à-dire qu'elle possède l'attribut de rappel), nous accédons à la logique de fonction réelle en supprimant le décorateur Click.
  • Exécution de la commande : Une fois que nous récupérons la fonction non décorée, nous passons les arguments et l'appelons, comme si nous invoquions directement une fonction Python.

3. Exemples de commandes CLI

Considérons quelques exemples de commandes dans un module de projet que les utilisateurs peuvent appeler de manière interactive via le chat :

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]")
Copier après la connexion

Exécution de l'interface de discussion

Pour exécuter le système de chat interactif :

  1. Assurez-vous que vos modules (comme le projet) sont répertoriés dans command_modules.
  2. Exécutez la commande :
@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]")
Copier après la connexion

Une fois la session démarrée, les utilisateurs peuvent saisir des commandes telles que :

python your_cli.py chat --project-path /path/to/project
Copier après la connexion

Le résultat sera affiché de manière bien formatée à l'aide de Rich Markdown :

You: project init You: project create "Homepage"
Copier après la connexion

Conclusion

En combinant Click pour la gestion des commandes, Rich pour le formatage Markdown et l'introspection Python, nous pouvons créer un système de discussion puissant et interactif pour les CLI. Cette approche vous permet de découvrir et d'exécuter dynamiquement des commandes tout en présentant le résultat dans un format élégant et lisible.

Points forts :

  • Exécution dynamique des commandes : L'introspection vous permet de découvrir et d'exécuter des commandes sans les coder en dur.
  • Rich Output : L'utilisation de Rich Markdown garantit que le résultat est facile à lire et visuellement attrayant.
  • Flexibilité : Cette configuration permet une flexibilité dans la structure et l'exécution des commandes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!