見出し画像

レンタルサーバでWebアプリ作り:Webアプリの修正(ChatGPT組み込み)

ロリポップレンタルサーバではできることが限られていたので、ホスティングサービスを使ってWebアプリを公開するまでの道のりを記録します。

データ分析を仕事としているのでパソコンやITのことは多少は詳しいですが、インフラまわりは全くの素人です。そんな人が見て参考になる情報をまとめていきたいと思います。

背景

前回、HelloWorldを表示するだけのWebアプリ公開までを記事にしました。前回記事:https://note.com/cryptoscore/n/n2689730c3caa

DigitalOceanは「GitHubを更新したら自動でWebアプリも更新される」らしいので、その機能を使ってWebアプリを修正しようと思います。


修正1:インプットボックスを設ける

ロリポップレンタルサーバで動かしていた コレ をDigitalOceanでも動かすようにします。

フォルダ追加

今回index.htmlを作るので、flaskルールに基づいて「templates」フォルダを作成し、そこにindex.html(中身は後述)を作ります。

test_digitalocean/
├ requirements.txt
├ Pipfile ※pipが自動作成
├ Pipfile.lock ※pipが自動作成
├ app.py
├ Procfile
├ gunicorn_config.py
├templates/
│ ┗index.html

app.pyの修正

追加PIPは不要です。
以下にマルっと書き換えます。

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/submit', methods=['POST'])
def recievingdata():
    text = request.form['text']
    try:
        with open('recieveddata.txt', 'w') as file:
            file.write(text)
        return jsonify(success=True)
    except Exception as e:
        return jsonify(success=False, error=str(e))

if __name__ == '__main__':
    app.run(debug=True)

index.htmlの中身

以下の内容でindex.htmlを作ります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Submit Text</title>
    <script>
        function sendData() {
            var xhr = new XMLHttpRequest();
            var url = "/submit";
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    var json = JSON.parse(xhr.responseText);
                    if (json.success) {
                        document.getElementById("result").innerHTML = "Success!";
                    } else {
                        document.getElementById("result").innerHTML = "Failed: " + json.error;
                    }
                }
            };
            var data = "text=" + document.getElementById("inputText").value;
            xhr.send(data);
        }
    </script>
</head>
<body>
    <input type="text" id="inputText">
    <button onclick="sendData()">送信</button>
    <div id="result"></div>
</body>
</html>

ローカルで試し打ち

app.pyでF5を押してデバッグ実行し、「http://127.0.0.1:5000」に行って、インプットボックスに適当な文字を入力し、送信ボタンをおしたら、test_digitaloceanフォルダの直下に「recieveddata.txt」が作成されて中身に入力した文字が入っていれば、成功です。

GitHubへプッシュ

前回の記事を参考に、修正した app.py と追加した templates/index.html をGitHubにプッシュしましょう。
前回記事:https://note.com/cryptoscore/n/n2689730c3caa

DigitalOceanで勝手にデプロイ

DigitalOceanのApp画面に行くと、勝手にデプロイが始まっています!
3分程度待つとデプロイが完了します。
※ 自動連携って、便利だけどトラブルにもなりそうとちょっと心配になりました。設定で「自動連携するな」もできるみたいです。

稼働確認

WebApp画面に行って、インプットボックスに適当な文字を入力し、送信ボタンを押して、Success!と出れば、第一段階成功。

次に、DigitalOceanのApp画面にあるConsoleへ行き、黒い画面のところで以下のコマンドを打ちます。

ls
more recieveddata.txt

lsコマンドを打って recieveddata.txt が作られており、moreコマンドで入力文字が書かれていれば、大成功です。



修正2:ChatGPTに質問する

今度は、以下の記事の内容をDigitalOcean上に作ります。https://note.com/cryptoscore/n/n4b2117672bd5

.envの作成

openaiのAPIキーを発行し(https://platform.openai.com/api-keys)、「.env」というテキストファイルを作り、その中に発行したAPIキーを入れます。****** のところに、発行したAPIキーを貼り付けます。

OPENAI_API_KEY='************'

<補足>
OpenAI APIキー発行所で新たに発行する際、発行してもすぐ削除されてしまう事件が頻発。原因は、「GitHubの閲覧設定をPublicにしていたから」でした。
どうやらOpenAIがネット上を調べているみたいで、「そのキーはネットに晒されているので削除しました」というメールが来ていました。
ということで、OpenAIのAPIキーをGitHubに載せる場合は、Privateで作りましょう。

.env を加えたフォルダ構成は、以下のようになります。
test_digitalocean/
├ requirements.txt
├ Pipfile ※pipが自動作成
├ Pipfile.lock ※pipが自動作成
├ app.py
├ Procfile
├ gunicorn_config.py
├ templates/
│ ┗index.html
├ .env

各種ファイルの更新

requirements.txt
openai と dotenv を追加します。以下のようになります。

Flask
gunicorn
openai
python-dotenv

requirements.txtを更新したら、pipも流しておきましょう。

pipenv install -r requirements.txt
pipenv lock

app.py
load_dotenvで.envのopanai_api_keyを読み込み、chatgptの機能を組み込みます。以下のような内容になります。

from flask import Flask, render_template, request, jsonify
import uuid
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv() #OpenAIのAPIキーをセット
client = OpenAI()

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')


@app.route('/submit', methods=['POST'])
def recievingdata():
    text = request.form['text']
    unique_id = str(uuid.uuid4())
    filename = f"{unique_id}.txt" 

    #--- chat gpt -------#
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": text},
        ]
    )
    res_txt = response.choices[0].message.content

    #--- save ----------#
    try:
        with open(filename, 'w') as file:
            file.write(res_txt) 
        return jsonify(success=True, user_id=unique_id, response=res_txt) 
    except Exception as e:
        return jsonify(success=False, error=str(e))


if __name__ == '__main__':
    app.run(debug=True)

index.html
上に書いている「修正1」のHTML文から、`if(json.success)`の中身(★が付いたところ)を変更しただけです。全体は以下のようになります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Submit Text</title>
    <script>
        function sendData() {
            var xhr = new XMLHttpRequest();
            var url = "/submit";
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    var json = JSON.parse(xhr.responseText);
                    if (json.success) {
                        document.getElementById("result").innerHTML = "Success! Your ID: " + json.user_id + ". response= " + json.response; //★
                    } else {
                        document.getElementById("result").innerHTML = "Failed: " + json.error;
                    }
                }
            };
            var data = "text=" + document.getElementById("inputText").value;
            xhr.send(data);
        }
    </script>
</head>
<body>
    <input type="text" id="inputText">
    <button onclick="sendData()">送信</button>
    <div id="result"></div>
</body>
</html>

GitHubへプッシュ→自動デプロイ

GitHubへ更新ファイルをプッシュすると、DigitalOceanで勝手に更新してくれます。Pipfile.lock や .env ファイルのプッシュも忘れずに。

デプロイが終わったら、Webアプリページに行って、例えば「大谷翔平の誕生日は?」と入れて、「〇月×日です」と帰ってくれば成功です。

さて、次はロリポップで実装できなかった”テケテケ表示”にチャレンジします。


最後まで見ていただきありがとうございました!
一度慣れてしまえば、とても簡単にデプロイできました。こんなことなら早くロリポップを卒業しておけばよかった。。


DigitalOceanのアカウント登録
(200ドル分チケット付き)

以下は紹介リンクですが、ここから手続きを進めてもらえると200ドル分の無料チケット(有効期間2ヶ月)がもらえるようですので、ぜひご活用ください。
※ 2023/12/29時点


この記事が気に入ったらサポートをしてみませんか?