
レンタルサーバで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時点