LaravelのHTTPテストのassertSeeで文字列がエスケープされないようにする

問題

LaravelのHTTPテストで、assertSeeやassertSeeTextを使って、HTMLの中に特定の文字列が含まれていることをテストすることがあります。

しかし、デフォルトでは、これらのメソッドはHTMLエスケープされた文字列を検索するため、意図した通りにテストが通らないことがあります。

例えば、次のようなコードを書いて、HTMLの中に<h1>hello</h1>の文字があるかどうかをテストすると、失敗します。

// コントローラーのサンプルアクション
public function index() {
    return view('welcome', ['message' => '<h1>hello</h1>']);
}

// テストケース
public function testExample() {
    $this->get('/')
        ->assertSee('<h1>hello</h1>');
}

この失敗の理由は、assertSee メソッドがデフォルトでHTMLエスケープされた文字列を検索するためです。

解決策

この問題に対処するには、assertSeeassertSeeTextメソッドに第二引数としてfalseを渡します。

これにより、メソッドはHTMLエスケープされた文字列の検索を行わなくなり、生のHTMLタグの存在を確認できるようになります。

// テストケース
public function testExample() {
    $this->get('/')
        ->assertSee('<h1>hello</h1>', false);
}

この変更により、LaravelはHTMLタグをエスケープせずにそのままの形でテスト対象の文字列として認識し、期待通りのテスト結果を得ることができます。

参考

asdfを使ってPythonとPoetryをインストールする

概要

asdfを使用してPythonとPoetryをインストールする手順を説明します。

まずはmacOSにasdfをインストールする方法を確認しましょう。こちらの記事を参考にしてください。

Pythonのインストール

  1. Pythonプラグインを追加

    Pythonプラグインをインストールするには、次のコマンドを実行します。

    % asdf plugin add python
    
  2. 利用可能なPythonバージョンの確認

    インストール可能なPythonバージョンを確認するには、次のコマンドを実行します。

    % asdf list all python
    
  3. .tool-versionsファイルを編集

    プロジェクトディレクトリに .tool-versions ファイルを作成し、インストールするPythonのバージョンを指定します。

    python 3.11.6
    

    ファイルの内容を確認します。

    % cat .tool-versions 
    Python 3.11.6
    
  4. Pythonをインストール

    .tool-versionsファイルのあるディレクトリで、以下のコマンドを実行します。

    % asdf install
    

    指定したバージョンのPythonがインストールされます。
    インストールが成功したことを確認するために、以下のコマンドを実行します。

    % python --version
    Python 3.11.6
    

Poetryのインストール

  1. Poetryプラグインを追加

    Poetryプラグインをインストールするには、次のコマンドを実行します。

    % asdf plugin-add poetry
    
  2. 利用可能なPoetryバージョンの確認

    インストール可能なPoetryバージョンを確認するには、次のコマンドを実行します。

    asdf list all poetry
    
  3. .tool-versionsファイルを編集

    .tool-versionsファイルにPoetryのバージョンを追記します。

    python 3.11.6
    poetry 1.7.1
    

    注意: .tool-versionsファイルの改行コードはLFであることを確認してください。

  4. Poetryをインストール

    .tool-versionsファイルのあるディレクトリで、以下のコマンドを実行します。

    % asdf install
    

    指定したバージョンのPoetryがインストールされます。
    インストールが成功したことを確認するために、以下のコマンドを実行します。

    % poetry --version
    Poetry version 1.7.1
    

以上で、asdfを使用してPythonとPoetryをインストールする手順が完了しました。

Homebrewを使ってmacOSにasdfをインストールする

概要

Homebrewを使用してmacOSにasdfをインストールする手順を説明します。
asdfは、複数のプログラミング言語のバージョン管理ツールです。
これを使えば、簡単に異なるバージョンの言語ランタイムを切り替えることができます。

手順

公式サイトの手順を参考にして、Homebrewを使ってmacOSにadsfをインストールします。

  1. Homebrewをインストールする

    Homebrewをインストールします。Homebrewはパッケージ管理ツールで、コマンドラインからさまざまなソフトウェアを簡単にインストールできます。
    Homebrewのインストール方法は、公式サイトを参考にしてください。

  2. asdfをインストールする

    Homebrewを使って、asdfを簡単にインストールできます。以下のコマンドを実行します。

    brew install asdf
    
  3. asdfを設定する

    asdfをインストールしたら、~/.zshrcに必要なコードを追加します。
    以下のコマンドを実行して、設定を追加します。

    echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ${ZDOTDIR:-~}/.zshrc
    

    このコマンドは、asdfの設定をシェルの設定ファイルに追加します。
    設定を反映させるために、ターミナルを再起動してください。

    zsh以外のシェルを使用している場合の設定方法は、asdfの公式サイトを参考にしてください。

  4. インストールを確認する

    インストールが正常に完了したか確認するために、以下のコマンドを実行します。

    asdf version
    

    ターミナルにasdfのバージョンが表示されれば、インストールが成功しています。

これで、macOSにasdfが正常にインストールされ、使用できるようになりました。
詳細な情報やドキュメンテーションは、asdfの公式サイトを参照してください。

ChatGPTのように文字を少しずつ表示する

概要

Amazon Bedrock上で動作するAnthropicのClaude 2を使用して、ChatGPTのようにテキストをリアルタイムで表示するWebアプリケーションを作成する方法を説明します。

ソースコード

使い方

  1. .envファイルの設定

    Amazon Bedrockを使用するために必要なAWSの設定を含む.envファイルを編集します。

    Amazon Bedrockを使用するためのAWSの情報を設定します。

    AWS_ACCESS_KEY_ID=あなたのアクセスキー
    AWS_SECRET_ACCESS_KEY=あなたのシークレットキー
    AWS_REGION=使用するAWSリージョン
    
  2. Docker Composeの起動

    次のコマンドでDocker Composeを起動します。

    docker compose up -d --build
    
  3. アクセス

    ブラウザでhttp://localhost:8080/にアクセスします。

  4. WebSocket接続

    「(1)WebSocketに接続する」ボタンを押してWebSocketに接続します。

  5. プロンプトの送信

    プロンプトを入力し、「(2)プロンプトを送信する」ボタンを押します。

プログラムの解説

ブラウザとサーバーはWebSocketを通じて通信します。

サーバー側では、PythonでWebSocket接続を待ち受け、Anthropic Claude 2モデルに問い合わせを行い、結果をリアルタイムでクライアントに送信します。

サーバーサイド

サーバーのserver.pyはポート6789でWebSocketの接続を待ち受けます。

async def main():
    async with websockets.serve(echo, "0.0.0.0", 6789):
        await asyncio.Future()  # プログラムが終了しないようにする

メッセージを受信すると、BedrockのAPIを実行して結果を返します。

async def echo(websocket, path):
    """WebSocket経由でメッセージを受信し、応答を返す"""
    async for message in websocket:
        logging.info(f"Received message: {message}")
        async for response in invoke_bedrock(message):
            logging.info(f"Sending response: {response}")
            await websocket.send(response)

BedrockのAPIを実行すると、結果がストリームで返ってきます。

response = bedrock.invoke_model_with_response_stream(
    modelId='anthropic.claude-v2',
    accept='application/json',
    contentType='application/json',
    body=body
)

Bedrockから受け取った結果を返します。

stream = response.get('body')
if stream:
    for event in stream:
        chunk = event.get('chunk')
        if chunk:
            decoded = json.loads(chunk.get('bytes').decode())
            yield(decoded['completion'])

クライアントサイド

クライアントのindex.htmlはサーバーとのWebSocket接続を確立し、ユーザーの入力に基づいてメッセージを送信し、受信した応答を表示します。

// サーバーとのWebSocket接続を確立
ws = new WebSocket("ws://127.0.0.1:6789/");

// メッセージを送信
const message = document.getElementById("message").value;
ws.send(message);

// 受信した応答を表示
ws.onmessage = function (event) {
    log.textContent += event.data;
};

Amazon BedrockとAnthropic Claude 2を使用して、リアルタイムでテキストを表示するWebアプリケーションの作成方法を紹介しました。