from flask import Flask, request, render_template_string
from openai import OpenAI
import base64, os
#apikeyは直書きしない
client = OpenAI(api_key="your_apikey")
app = Flask(__name__)
#分類させるジャンル一覧
GENRES = [
"ストリート","ヴィンテージ","カジュアル","韓国",
"綺麗め","ガーリー","y2k","モード",
"アウトドア","スポーツミックス","ミニマル"
]
# HTML(1ファイルで完結させるため render_template_string を使用)
HTML = """
<!doctype html>
<html><head><meta charset="utf-8"><title>Fashion Diagnose</title>
<style>
body{
background:#fff;
color:#000;
font-family: Georgia, serif;
padding:60px 80px;
line-height:1.7;
font-size:18px;
display:flex;
flex-direction:column;
align-items:center;
text-align:center;
}
h1{
font-size:48px;
font-weight:normal;
margin-bottom:60px;
letter-spacing:0.02em;
}
h2{
font-size:20px;
font-weight:normal;
text-transform:capitalize;
margin-top:60px;
}
img{ margin:60px 0; max-width:550px; }
form{ margin-bottom:80px; }
input[type=submit]{
background:none;
border:1px solid #000;
padding:14px 28px;
font-family:Georgia, serif;
font-size:16px;
cursor:pointer;
}
</style>
</head><body>
<h1>Fashion Diagnose</h1>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="image" accept="image/*" required>
<input type="submit" value="Analyse">
</form>
{% if img64 %}
<img src="data:image/png;base64,{{img64}}">
{% endif %}
{% if genre %}
<h2>Genre</h2>
<p>{{genre}}</p>
{% endif %}
{% if suggestion %}
<h2>Improvement</h2>
<p style="white-space:pre-line">{{suggestion}}</p>
{% endif %}
</body></html>
"""
# デフォルト(None)
@app.route("/", methods=["GET","POST"])
def index():
genre = None
suggestion = None
img64 = None
if request.method=="POST":
# POSTされた画像を読み込む
file = request.files["image"]
b = file.read()
# htmlに埋める用に base64に
img64 = base64.b64encode(b).decode()
# pngでもjpegでも勝手に MIME を自動で入れてくれる
mime = file.mimetype # ← jpeg / png どっちでも
data_url = f"data:{mime};base64,{img64}"
# ----- genre -----
# system prompt で「候補のうち1個だけ返せ」と指示
sys = f"""
あなたはプロのスタイリスト。
以下の候補の中から **1つだけ** 正確に返す。
返すときはちょうど同じ文字列だけ返す。余計な語は一切禁止。
候補: {",".join(GENRES)}
""".strip()
r1 = client.chat.completions.create(
model="gpt-5-mini",# gpt-5-miniでコスト低め
messages=[
{"role":"system","content":sys},
{
"role":"user",
"content":[
{"type":"image_url","image_url":{"url":data_url}},
{"type":"text","text":"ジャンルは?"}# 画像+テキスト一緒に投げてる
]
}
],
)
genre = r1.choices[0].message.content.strip()
# ----- improvement -----
sys2 = f"""
あなたは{genre}ジャンルのプロ。
画像の服装を見て、改善提案を段落テキストで出す。
bullet記号は使わない。
""".strip()
r2 = client.chat.completions.create(
model="gpt-5-mini",
messages=[
{"role":"system","content":sys2},
{
"role":"user",
"content":[
{"type":"image_url","image_url":{"url":data_url}},
{"type":"text","text":"改善ポイントを"}
]
}
],
)
suggestion = r2.choices[0].message.content.strip()
# HTMLに値を入れて返す
return render_template_string(HTML, genre=genre, suggestion=suggestion, img64=img64)
if __name__=="__main__":
app.run(debug=True)# debug=True はローカル開発専用(本番NG)