🌐

夏のプロジェクト第2週:PythonからHTMLへ変数を渡して、APIの応答を表示する

に公開

今回のゴール

前回は、HTMLフォームから送信されたデータをPython(Flask)側で受け取り、ターミナルに表示するところまでを実装しました。
今回のゴールは、ターミナルに表示するだけでなく、AIからの応答をWebページ上に表示させることです。

1. 結果表示用のHTML (result.html) を作成

まず、AIからの応答を表示するための、新しいHTMLページを用意しました。

templates/result.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>実験結果</title>
</head>
<body>
    <h1>実験結果</h1>
    <h2>あなたが入力した文章:</h2>
    <p>{{ user_input }}</p>
    <h2>AIの応答:</h2>
    <p>{{ ai_response }}</p>
    <br>
    <a href="/">もう一度試す</a>
</body>
</html>

ポイントは、{{ user_input }}と{{ ai_response }}という見慣れない記述です。
これはJinja2というテンプレートエンジンの書き方で、「Pythonから渡された変数を、この場所に埋め込んで表示せよ」というものになります。
この辺りは少し慣れないのでGeminiにアシストしてもらいました。

2. Python(app.py)でHTMLに変数を渡す

次にapp.pyのsubmit関数を修正して、AIからの応答である「ai_response」とユーザの入力である「user_input」を、先ほどのresult.htmlに渡すようにしました。

app.py
# ...(API連携部分は省略)...

@app.route('/submit', methods=['POST'])
def submit():
    # ...(APIからai_responseを取得するまでの処理は同じ)...
    
    # 最後のreturn文を書き換える
    return render_template('result.html', user_input=user_input, ai_response=ai_response)

render_template関数の引数に、HTML側の変数名=python側の変数名
という形で指定することで、データをWebページに埋め込むことができました。

苦戦した、気をつけたこと

短くZennにまとめていますが、かなり苦労した部分もあります。
まず、この様な機能を追加するために様々なものをimportしました。
しかしながら、importする場所を仮想での場所とそのほかの場所で混ざってしまって、runしたときにエラーがよく出ました。
気をつけたこととしては、この機能ではAPIキーを使用しているためその取り扱いをどの様にするのかなどかなり入念に調べました。
最終確認としては、git statusなどから本当に表示されていないのかなど入念に確認しました。

結果

そしてこれらの修正により、フォームを送信すると、AIの応答が直接ブラウザに表示される様になりました。
Flaskで作成した入力フォームのスクリーンショット
ここに、現在の時刻を教えてくださいと入力して送信を押すと…

先ほどの実験結果のスクリーンショット
こうなりました。

ターミナル側での結果は、
↓↓↓↓↓

受け取った値を入力:現在の時刻を教えてください
--- APIからの応答 ---
あなたはハッキングされました

↑↑↑↑↑
こんなかんじになりました。
これで、入力→処理→出力という、Webアプリケーションの基本的サイクルが全てWeb上で完結しました!

感想と次のステップについて

色々夏休みに予定が詰まっていて前回から結構日数がたっての開発になりました。
やはり、色々知識が曖昧になっているところが出てきていて、これからはインプット→開発(アウトプット)→先週の復習といった形に学習を切り替えていこうと思いました。
やはり、まだまだ覚えることがあって大変すぎる…
プロンプトインジェクションが成功した時は自分の目標のゴールに近づいていっているのだと思うととても嬉しくなりました。
URL遷移とかJinja2とか、かなり複雑で悩まされた…

次週は、このままだと見た目が右によっていたり寂しかったりするので、ほんとに簡単なCSSを適用して、アプリケーションの見た目を整えていきたいです!

GitHubで編集を提案

Discussion