ホームページ  >  記事  >  バックエンド開発  >  イントロスペクション、クリック、リッチフォーマットを使用して Python CLI の対話型チャットを構築する方法

イントロスペクション、クリック、リッチフォーマットを使用して Python CLI の対話型チャットを構築する方法

Barbara Streisand
Barbara Streisandオリジナル
2024-10-26 11:00:29812ブラウズ

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

CLI をよりインタラクティブかつダイナミックにしたいと考えたことがある場合は、リアルタイムのコマンド対話システムを構築することがその答えになる可能性があります。 Python のイントロスペクション機能、コマンドの管理に Click、出力の書式設定に Rich を活用することで、ユーザー入力にインテリジェントに応答する強力で柔軟な CLI を作成できます。各コマンドを手動でハードコーディングする代わりに、CLI がコマンドを自動的に検出して実行できるため、ユーザー エクスペリエンスがよりスムーズで魅力的なものになります。

カラフルなコンソールのカオス: クリック コマンドとリッチな出力が融合します。なぜなら、端末ですらスタイリッシュに見せたがるからです!

クリックとマークダウンを使用する理由

クリックすると、コマンドの管理、引数の解析、ヘルプの生成が簡素化されます。また、コマンドの構造化とオプションの処理も簡単になります。

Rich を使用すると、美しくフォーマットされた Markdown をターミナルに直接出力できるため、機能的なだけでなく視覚的にも魅力的な結果が得られます。

これら 2 つのライブラリと Python イントロスペクションを組み合わせることで、豊富で読みやすい形式で出力を表示しながら、コマンドを動的に検出して実行する対話型チャット機能を構築できます。 実際的な例については、StoryCraftr が同様のアプローチを使用して AI 主導の執筆ワークフローを合理化する方法をご覧ください: https://storycraftr.app.

インタラクティブなチャット システムの構築

1. 基本的なチャットコマンドの設定

チャット コマンドはセッションを初期化し、ユーザーが CLI を操作できるようにします。ここでは、ユーザー入力をキャプチャし、適切なクリック コマンドに動的にマッピングされます。

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. コマンドを検出して実行するためのイントロスペクション

Python イントロスペクションを使用して、使用可能なコマンドを動的に検出し、実行します。ここで重要な部分の 1 つは、Click コマンドが装飾された関数であるということです。実際のロジックを実行するには、装飾されていない関数 (つまり、コールバック) を呼び出す必要があります。

イントロスペクションを使用してコマンドを動的に実行し、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)

これはどのように作動しますか?

  • 入力解析: コマンドライン引数のように入力を処理するために shlex.split を使用します。これにより、引用符で囲まれた文字列と特殊文字が正しく処理されるようになります。
  • モジュールとコマンドの検索: 入力は module_name と command_name に分割されます。コマンド名は、Python 関数名と一致するようにハイフンをアンダースコアに置き換えるように処理されます。
  • イントロスペクション: getattr() を使用して、モジュールからコマンド関数を動的に取得します。 Click コマンドの場合 (つまり、コールバック属性がある場合)、Click デコレーターを削除して実際の関数ロジックにアクセスします。
  • コマンドの実行: 装飾されていない関数を取得したら、Python 関数を直接呼び出しているかのように、引数を渡して呼び出します。

3. CLI コマンドの例

ユーザーがチャットを通じて対話的に呼び出すことができる、プロジェクト モジュール内のサンプル コマンドをいくつか考えてみましょう。

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]")

チャットインターフェイスの実行

対話型チャット システムを実行するには:

  1. モジュール (プロジェクトなど) が command_modules にリストされていることを確認してください。
  2. 次のコマンドを実行します。
@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]")

セッションが開始されると、ユーザーは次のようなコマンドを入力できます:

python your_cli.py chat --project-path /path/to/project

出力は、Rich Markdown を使用して整形式で表示されます。

You: project init You: project create "Homepage"

結論

コマンド管理用の Click、Markdown フォーマット用の Rich、および Python イントロスペクションを組み合わせることで、CLI 用の強力でインタラクティブなチャット システムを構築できます。このアプローチにより、出力をエレガントで読みやすい形式で表示しながら、コマンドを動的に検出して実行できます。

主なハイライト:

  • 動的コマンド実行: イントロスペクションを使用すると、ハードコーディングせずにコマンドを検出して実行できます。
  • リッチ出力: リッチ マークダウンを使用すると、出力が読みやすく、視覚的に魅力的になります。
  • 柔軟性: この設定により、コマンドの構造と実行に柔軟性が与えられます。

以上がイントロスペクション、クリック、リッチフォーマットを使用して Python CLI の対話型チャットを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。