前回危うくそのままWebアプリを公開しそうになったけど、まずはなんで公開しちゃいけないか説明しておくね
お願いします!
今のコードには、葵専用のAPIキーが直接書き込んであるでしょ?
これをそのまま公開すると、世界中の誰でも「葵の代わりに、葵の枠を使って」AIが使い放題になっちゃうんだ
そうか、家の玄関に鍵を挿しっぱなしで出かけるようなものだもんね
そういうこと!だから、APIキーは直接コードに書き込むんじゃなくて、「環境変数」っていう見えない箱に入れておくのが基本なんよ
環境変数?
簡単に言うと、パソコンの中にこっそり隠しておける「自分専用のメモ帳」みたいなものかな
とはいえ、今回は無料枠で利用にしてるのもあって、利用上限の面でも自分のAPIキーを利用して公開するのはあまり現実的ではないから、今回はユーザーにAPIキーを発行してもらって利用する形式にしようと思うよ
なるほど!それなら安心だね!
ということで、まずはAPIキーを入力する画面を作るよ!
まずはAPIキーを入力してもらう場所をサイドバーに作成しようか
# st.title()の上に追加
with st.sidebar:
st.title("⚙️ 設定")
api_key = st.text_input("Gemini API Keyを入力", type="password")
おー!急にサイドバーが現れた!!
あとは、api_keyが関数に渡されるようにすればいいだけだよ!
# generate_response関数にapi_keyを渡すように変更
def generate_response(skill_name, api_key):
# AIの設定
client = genai.Client(api_key=api_key)
prompt = f"""
RPGのゲームマスターとして、技名「{skill_name}」の設定を作ってください。
以下のJSONフォーマットで出力してください。
{{
"name": "{skill_name}",
"element": "属性(火、水、風、雷、光、闇から選択)",
"power": "威力(10〜999の数値)",
"mp_cost": "消費MP(5〜100の数値)"
}}
"""
response = client.models.generate_content(
model='gemini-2.5-flash',
contents=prompt,
config={'response_mime_type': 'application/json'}
)
return json.loads(response.text)
この時、ついでに「GEMINI_API_KEY」は消しておこうね!
GEMINI_API_KEY = "AIZa~" # この部分を削除(コメントアウトはダメ)
これでプログラムの中にはAPIキーが書かれてないから安心だね!
あとは、関数を呼び出す箇所もapi_keyを渡すように変更しつつ、api_keyが空欄の時や関数がエラーを返した時はエラーメッセージを出すようにしよう!
# ボタンが押された時の処理
if st.button("技の設定を作る"):
if not api_key:
st.error("左のサイドバーにAPIキーを入力してください!")
elif not skill_name:
st.warning("技の名前を入力してください。")
else:
try:
# ここにAIを呼び出す処理を書く
response = generate_response(skill_name, api_key)
st.write(f"技名: {skill_name}")
st.write(f"属性: {response['element']}")
st.write(f"威力: {response['power']}")
st.write(f"消費MP: {response['mp_cost']}")
except Exception as e:
st.error(f"エラーが発生したよ。APIキーが正しいか確認してね!\n{e}")
これで一通り問題なく動くようになったね!
そうだね!ひとまずこれで完成だけど、ついでに「技の設定」をブラウザに保存する機能を追加してみようか
おおー!それもあると良さそう!!
この時点での全体のプログラム
from google import genai
import json
import streamlit as st
# 技の名前を渡すと、AIがJSON形式で技の設定を返してくれる関数
def generate_response(skill_name, api_key):
# AIの設定
client = genai.Client(api_key=api_key)
prompt = f"""
RPGのゲームマスターとして、技名「{skill_name}」の設定を作ってください。
以下のJSONフォーマットで出力してください。
{{
"name": "{skill_name}",
"element": "属性(火、水、風、雷、光、闇から選択)",
"power": "威力(10〜999の数値)",
"mp_cost": "消費MP(5〜100の数値)"
}}
"""
response = client.models.generate_content(
model='gemini-2.5-flash',
contents=prompt,
config={'response_mime_type': 'application/json'}
)
return json.loads(response.text)
with st.sidebar:
st.title("⚙️ 設定")
api_key = st.text_input("Gemini API Keyを入力", type="password")
# 画面のタイトル
st.title("AIで技の設定を作ろう")
# ユーザーが技名を入力する欄
skill_name = st.text_input("技の名前を入力してください")
# ボタンが押された時の処理
if st.button("技の設定を作る"):
if not api_key:
st.error("左のサイドバーにAPIキーを入力してください!")
elif not skill_name:
st.warning("技の名前を入力してください。")
else:
try:
# ここにAIを呼び出す処理を書く
response = generate_response(skill_name, api_key)
st.write(f"技名: {skill_name}")
st.write(f"属性: {response['element']}")
st.write(f"威力: {response['power']}")
st.write(f"消費MP: {response['mp_cost']}")
except Exception as e:
st.error(f"エラーが発生したよ。APIキーが正しいか確認してね!\n{e}")
