
ChatGPTに画像からWebアプリを作ってもらう(プロトタイプ編)
画像からWebアプリ
普段コードを書かない人でもどの程度できるのかな?、と興味を持ったのが始まりでした。

ChatGPTに上記画像をアップロードしてこう聞きました。
あなた
添付画像のインタフェースを持つWebアプリのPythonコードを教えてください。
ChatGPTはこう回答しました。
ChatGPT
この画像には日本語のテキストが含まれているので、内容を理解するためにまずはそれを翻訳しましょう。その後、Pythonコードの作成に進むことができます。画像の中身を確認した後、Webアプリケーションのインターフェースに相当するPythonコードを提供します。
・・・
コードとHTMLテンプレートが提案されました。
ただ、Google Colaboratoryで動かしたかったので、確認する前に追加の依頼をしました。
Google Colabで動かすには?
あなた
上記をGoogle Colabで動かすには?
ChatGPT
Google ColabでWebアプリケーションを実行するためには、いくつかの追加的なステップを踏む必要があります。ColabはJupyterノートブックをホストする環境であり、そのままではWebサーバーを起動することはできませんが、ngrokというツールを使用して公開URLを介してFlaskアプリケーションにアクセスすることができます。
ここからしばらくうまくいきませんでした。
「flask-ngrokの内部でngrokを正しく起動できていない可能性があります。」という回答が続きます。
やりとりしている間に、ngrokのWebサイトにアクセスし、アカウントを作成したりしました。
結局以下を参考に、
こう質問を変えました。
pyngrok を使えばいいのでは?
あなた
!pip install flask pyngrok を使えばいいのではないですか?
ChatGPT
はい、その通りです。!pip install flask pyngrokを使用する方法もあり、この方法は特にPython環境やGoogle Colabでngrokを利用したい場合に簡単で効果的です。pyngrokはPythonからngrokを簡単に操作できるようにするラッパーライブラリで、Flaskアプリケーションと組み合わせて使用できます。
FlaskとPyngrokのセットアップ
!pip install flask pyngrok
Flaskアプリケーションのコードにpyngrokを組み込む:
from flask import Flask
from pyngrok import ngrok
app = Flask(__name__)
# ngrokトンネルの開始
public_url = ngrok.connect(5000)
print(f'ngrok tunnel "{public_url}" created')
@app.route("/")
def home():
return "<h1>Hello from Flask!</h1>"
if __name__ == "__main__":
app.run(port=5000)
・・・
ただし、ngrokを使用する場合は、トンネルURLが公開されている間は、インターネット上から誰でもアクセスできる点に注意してください。セキュリティ上のリスクを避けるために、使用していない時はトンネルを閉じることを忘れないでください。
その後もすぐには動かず、何度かやりとりしています。
例えば以下のような内容です。
Flaskでrender_template関数を使用するとき、「デフォルトでtemplatesフォルダを(HTML)テンプレートファイルの場所として期待する」ということなので、templatesフォルダを作成。
ngrokのアクセストークンをGoogle Colabのシークレットで使えるということでしたが、「Colabの秘密情報(シークレット)をプログラムから直接アクセスする正式な方法は提供されていないため、このコードは機能しません」と言われて断念。
当初のレイアウトと違いますが、ngrok経由でテンプレートを割り当てたWebページを立ち上げられました。

タグ除去、正規化、分類関数
もう一度最初の画像(以下)をアップロードしました。

追加コードのオーダーを出します。
あなた
上記コードを利用し、添付画像のWebアプリに切り替えてください。
・HTMLタグ除去ボタンをクリックしたらタグ除去
・文章の正規化ボタンをクリックしたら正規化
・分類実行ボタンをクリックしたらテキスト分類を実行する
画像からの説明に基づいて、Webアプリケーションに機能を追加するためのコードの変更を行います。以下の機能を実装します:
1. HTMLタグを除去する機能。
2. テキストを正規化する機能。
3. テキストを分類する機能。
まず、必要な機能を実装するためのPython関数を定義します。その後、Flaskルートでこれらの関数を呼び出すコードを追加します。ただし、実際のテキスト分類ロジック(機械学習モデルなど)は、この例ではダミーのものを使用し、具体的な実装は省略します。
from flask import Flask, render_template, request
from pyngrok import ngrok
import re
app = Flask(__name__)
# HTMLタグを除去する関数
def remove_html_tags(text):
clean = re.compile('<.*?>')
return re.sub(clean, '', text)
# テキストを正規化する関数
def normalize_text(text):
text = text.lower()
text = re.sub(r'\s+', ' ', text) # 余分な空白を削除
# ここに追加の正規化ステップを加える
return text
# テキストを分類するダミー関数
def categorize_text(text):
# 実際には機械学習モデルを呼び出して結果を得る
categories = {
'AI': 85.1,
'動画生成': 70.3,
'ドローン': 50.5
}
return categories
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
text = request.form['text']
if 'remove_tags' in request.form:
text = remove_html_tags(text)
elif 'normalize' in request.form:
text = normalize_text(text)
elif 'classify' in request.form:
categories = categorize_text(text)
return render_template('web_app_if_claude.html', categories=categories)
return render_template('web_app_if_claude.html', processed_text=text)
return render_template('web_app_if_claude.html', processed_text='')
if __name__ == '__main__':
public_url = ngrok.connect(5000)
print(f"ngrok tunnel URL: {public_url}")
app.run(port=5000)
この後のやりとりでは以下を進めました。
Flaskアプリケーションに統合するためにHTMLテンプレートの改修
キーワードマッチングでテキスト分類する関数を実装
正規化のステップを追加
結果、仕上がったコードは以下です。
from flask import Flask, render_template, request
from pyngrok import ngrok
import re
import unicodedata
app = Flask(__name__)
# ここでngrokのアクセストークンを設定
ngrok.set_auth_token("アクセストークン")
# HTMLタグを除去する関数
def remove_html_tags(text):
clean = re.compile('<.*?>')
return re.sub(clean, '', text)
# テキストを正規化する関数
def normalize_text(text):
# 文字列を小文字に変換
text = text.lower()
# 余分な空白を単一の空白に置換
text = re.sub(r'\s+', ' ', text)
# 全角文字を半角文字に変換
text = unicodedata.normalize('NFKC', text)
# 数字を<num>に置換
text = re.sub(r'\d+', '<num>', text)
# 不要な記号を削除(ここではアルファベットと数字、アンダースコア以外を削除)
text = re.sub(r'[^\w\s]', '', text)
# ...他の正規化ステップ...
return text
def categorize_text(text):
# キーワードに基づいたカテゴリーとそのキーワードのリスト
keyword_categories = {
'AI': ['人工知能', '機械学習', 'ディープラーニング', 'AI', 'ai']],
'動画生成': ['ビデオ制作', 'ビデオ編集', '映画制作'],
'ドローン': ['ドローン', 'クアッドコプター', 'UAV', '無人航空機']
}
# 分類結果を格納するための辞書
categories = {}
# テキストを小文字に変換
lower_text = text.lower()
# 全てのカテゴリーに対してキーワードが含まれているかをチェックし、
# 含まれていればそのカテゴリーの確率を高く設定
for category, keywords in keyword_categories.items():
# カテゴリーごとのマッチングキーワード数をカウント
match_count = sum(lower_text.count(keyword) for keyword in keywords)
if match_count > 0:
# キーワードが一致すれば高確率を設定(例:マッチング数 × 20%)
categories[category] = match_count * 20.0
else:
# キーワードが一致しなければ低確率を設定(例:5%)
categories[category] = 5.0
return categories
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
text = request.form['text']
if 'remove_tags' in request.form:
text = remove_html_tags(text)
elif 'normalize' in request.form:
text = normalize_text(text)
elif 'classify' in request.form:
categories = categorize_text(text)
return render_template('web_app_interface.html', categories=categories)
return render_template('web_app_interface.html', processed_text=text)
return render_template('web_app_interface.html', processed_text='')
if __name__ == '__main__':
public_url = ngrok.connect(5000)
print(f"ngrok tunnel URL: {public_url}")
app.run(port=5000)
実行例
ChatGPTに作ってもらったHTMLタグ付き記事をペースト。

HTMLタグ除去を実行。

文章の正規化を実行。

分類実行。
(100%を超えるような処理になっています)

セキュリティに関する備忘録
ただ、アクセストークンをソースコードに直接記述することはセキュリティ上危険です。
プロトタイプなのでここで一区切りとしましたが、ChatGPTに聞いた以下の方法を試すつもりです。
(下記の1は動作確認済みです)
ChatGPT
Google Colabには、環境変数や構成ファイルを使用せずに秘密情報を安全に保存するための組み込み機能は現在のところ提供されていません。しかし、ノートブックのセキュリティを向上させるためにいくつかの方法を用いることができます。
Colabで秘密情報を扱う際の一般的なアプローチは次のとおりです:
1. 入力プロンプトを使用する: セル内で入力プロンプトを使用してユーザーから秘密情報を受け取ります。この情報はノートブックのセルに表示されません。
from getpass import getpass
ngrok_token = getpass('Enter your ngrok token: ')
ngrok.set_auth_token(ngrok_token)
2. Googleドライブを使用する: 秘密情報を含むファイルをGoogleドライブに保存し、Colabから安全にアクセスします。
from google.colab import drive
drive.mount('/content/drive')
with open('/content/drive/My Drive/ngrok_token.txt', 'r') as file:
ngrok_token = file.read().strip()
ngrok.set_auth_token(ngrok_token)
3. 環境変数: Colabセッションの環境変数に秘密情報を設定し、セッション終了時にこれらがクリアされることを利用します。
import os
# 環境変数にアクセストークンを設定
os.environ['NGROK_AUTH_TOKEN'] = 'ここにアクセストークンを入力'
# その後、環境変数からアクセストークンを読み取って使用
ngrok_token = os.getenv('NGROK_AUTH_TOKEN')
ngrok.set_auth_token(ngrok_token)
この方法で設定した環境変数は、Colabの現在のセッションにのみ存在し、セッションが終了すると失われます。
これらの方法の中で、特にgetpassを使用する方法は、秘密情報をノートブックに保存しないため、共有されたり、GitHubにプッシュされたりするリスクが最も低いです。ただし、getpassを使用する場合、ノートブックを再実行するたびに秘密情報を再入力する必要があります。
Googleドライブを使用する方法は、情報がドライブに保存されるため、一度設定すれば再入力の必要がなくなりますが、ファイルのアクセス管理には注意が必要です。
いずれの方法も、Colabノートブックを他人と共有する際には秘密情報が含まれないように注意してください。秘密情報は、共有する前に削除するか、別の方法で安全に管理してください。