Update app.py
Browse files
app.py
CHANGED
@@ -1,20 +1,25 @@
|
|
1 |
"""
|
2 |
-
Square Theory Generator (
|
3 |
-
|
4 |
-
2025โ05โ28
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
```bash
|
13 |
pip install --upgrade gradio matplotlib openai
|
14 |
export OPENAI_API_KEY="sk-..."
|
15 |
python square_theory_gradio.py
|
16 |
```
|
17 |
-
|
18 |
"""
|
19 |
|
20 |
import os
|
@@ -25,14 +30,12 @@ from matplotlib import patches, font_manager, rcParams
|
|
25 |
from openai import OpenAI
|
26 |
|
27 |
# -------------------------------------------------
|
28 |
-
# 0. ํ๊ธ ํฐํธ
|
29 |
# -------------------------------------------------
|
30 |
|
31 |
def _set_korean_font():
|
32 |
-
|
33 |
-
|
34 |
-
for cand in candidates:
|
35 |
-
if cand in available:
|
36 |
rcParams["font.family"] = cand
|
37 |
break
|
38 |
rcParams["axes.unicode_minus"] = False
|
@@ -40,7 +43,7 @@ def _set_korean_font():
|
|
40 |
_set_korean_font()
|
41 |
|
42 |
# -------------------------------------------------
|
43 |
-
# 1. OpenAI ํด๋ผ์ด์ธํธ
|
44 |
# -------------------------------------------------
|
45 |
if not os.getenv("OPENAI_API_KEY"):
|
46 |
raise EnvironmentError("OPENAI_API_KEY ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ์ธ์.")
|
@@ -48,7 +51,7 @@ if not os.getenv("OPENAI_API_KEY"):
|
|
48 |
client = OpenAI()
|
49 |
|
50 |
# -------------------------------------------------
|
51 |
-
# 2. Square
|
52 |
# -------------------------------------------------
|
53 |
|
54 |
def draw_square(words):
|
@@ -66,59 +69,69 @@ def draw_square(words):
|
|
66 |
return fig
|
67 |
|
68 |
# -------------------------------------------------
|
69 |
-
# 3. LLM
|
70 |
# -------------------------------------------------
|
71 |
SYSTEM_PROMPT = (
|
72 |
-
"๋๋ ํ๊ตญ์ด ์นดํผยท๋ธ๋๋ ๋ค์ด๋ฐ ์ ๋ฌธ๊ฐ์ด์ Square Theory
|
73 |
-
"์ฌ์ฉ์๊ฐ
|
74 |
-
"
|
75 |
-
"
|
|
|
|
|
76 |
)
|
77 |
|
78 |
|
79 |
-
def call_llm(seed: str
|
80 |
-
"""LLM ํธ์ถ โ JSON dict ๋ฐํ"""
|
81 |
resp = client.chat.completions.create(
|
82 |
-
model="gpt-
|
83 |
messages=[
|
84 |
{"role": "system", "content": SYSTEM_PROMPT},
|
85 |
{"role": "user", "content": seed},
|
86 |
],
|
87 |
temperature=0.9,
|
88 |
-
max_tokens=
|
89 |
)
|
90 |
raw = resp.choices[0].message.content.strip()
|
91 |
-
if debug:
|
92 |
-
print("LLM raw:", raw)
|
93 |
try:
|
94 |
data = json.loads(raw)
|
95 |
-
|
96 |
-
|
|
|
|
|
97 |
return data
|
98 |
|
99 |
# -------------------------------------------------
|
100 |
-
# 4. Gradio
|
101 |
# -------------------------------------------------
|
102 |
|
103 |
-
def generate(seed_word):
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
# -------------------------------------------------
|
109 |
-
# 5.
|
110 |
# -------------------------------------------------
|
111 |
-
with gr.Blocks(title="Square Theory
|
112 |
-
gr.Markdown("""#
|
113 |
seed = gr.Textbox(label="์๋ ๋จ์ด(TL)", placeholder="์: ๊ณจ๋ ")
|
114 |
-
run = gr.Button("
|
115 |
-
fig_out = gr.Plot(label="์ฌ๊ฐํ
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
brand_out = gr.Textbox(label="๋ธ๋๋ ๋ค์")
|
120 |
-
|
121 |
-
run.click(generate, inputs=seed, outputs=[fig_out, top_out, bottom_out, slogan_out, brand_out])
|
122 |
|
123 |
if __name__ == "__main__":
|
124 |
demo.launch()
|
|
|
1 |
"""
|
2 |
+
Square Theory Generator (10 best variations)
|
3 |
+
===========================================
|
4 |
+
2025โ05โ28ย v3 โ ํ ์
๋ ฅ โ ์ฐ์๋ ์ 10๊ฐ์ง ๊ฒฐ๊ณผ
|
5 |
+
------------------------------------------------
|
6 |
+
๋ณ๊ฒฝ ์์ฝ
|
7 |
+
---------
|
8 |
+
1. **LLM ํย ํ ํธ์ถ๋ก 10๊ฐ์ ์ฌ๊ฐํ ์ ์**
|
9 |
+
* JSON ๋ฐฐ์ด ํํ๋ก ๋ฐํ, ํ์ง์ด ๋์ ์์๋ก ์ ๋ ฌ (1ย โย 10)
|
10 |
+
2. **์ถ๋ ฅ**
|
11 |
+
* โ 1์ ์ ์์ ์ฌ๊ฐํ ๋์(Plot)
|
12 |
+
* โก 10๊ฐ ์ ์์ ๋งํฌ๋ค์ด ๋ฆฌ์คํธ๋ก ์ ๋ฆฌํ์ฌ ํ์
|
13 |
+
3. **UI ๊ฐ์ํ** : seed ์
๋ ฅย +ย ์คํ ๋ฒํผ + Plot + Markdown
|
14 |
+
4. **์๋ฌ ์ฒ๋ฆฌ ๊ฐํ**
|
15 |
+
|
16 |
+
์คํ๋ฒ
|
17 |
+
------
|
18 |
```bash
|
19 |
pip install --upgrade gradio matplotlib openai
|
20 |
export OPENAI_API_KEY="sk-..."
|
21 |
python square_theory_gradio.py
|
22 |
```
|
|
|
23 |
"""
|
24 |
|
25 |
import os
|
|
|
30 |
from openai import OpenAI
|
31 |
|
32 |
# -------------------------------------------------
|
33 |
+
# 0. ํ๊ธ ํฐํธ ์ค์
|
34 |
# -------------------------------------------------
|
35 |
|
36 |
def _set_korean_font():
|
37 |
+
for cand in ("Malgun Gothic", "NanumGothic", "AppleGothic", "DejaVu Sans"):
|
38 |
+
if cand in {f.name for f in font_manager.fontManager.ttflist}:
|
|
|
|
|
39 |
rcParams["font.family"] = cand
|
40 |
break
|
41 |
rcParams["axes.unicode_minus"] = False
|
|
|
43 |
_set_korean_font()
|
44 |
|
45 |
# -------------------------------------------------
|
46 |
+
# 1. OpenAI ํด๋ผ์ด์ธํธ
|
47 |
# -------------------------------------------------
|
48 |
if not os.getenv("OPENAI_API_KEY"):
|
49 |
raise EnvironmentError("OPENAI_API_KEY ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ์ธ์.")
|
|
|
51 |
client = OpenAI()
|
52 |
|
53 |
# -------------------------------------------------
|
54 |
+
# 2. Square Diagram
|
55 |
# -------------------------------------------------
|
56 |
|
57 |
def draw_square(words):
|
|
|
69 |
return fig
|
70 |
|
71 |
# -------------------------------------------------
|
72 |
+
# 3. LLM Prompt & Call
|
73 |
# -------------------------------------------------
|
74 |
SYSTEM_PROMPT = (
|
75 |
+
"๋๋ ํ๊ตญ์ด ์นดํผยท๋ธ๋๋ ๋ค์ด๋ฐ ์ ๋ฌธ๊ฐ์ด์ Square Theory ๋์ฐ๋ฏธ๋ค. "
|
76 |
+
"์ฌ์ฉ์๊ฐ ์ค ํ๋์ ๋จ์ด(tl)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ง์ด ๊ฐ์ฅ ๋ฐ์ด๋ ๊ฒ๋ถํฐ 10๊ฐ์ ์ ์์ JSON ๋ฐฐ์ด๋ก ๋ฐํํด๋ผ. "
|
77 |
+
"๊ฐ ๋ฐฐ์ด ์์๋ tl, tr, br, bl, top_phrase, bottom_phrase, slogan, brand ํ๋๋ฅผ ๊ฐ์ง๋ฉฐ, "
|
78 |
+
"์ฌ๊ฐํ ๋ค ๊ผญ์ง์ (tl>tr>br>bl)๊ณผ ๋ ํํยท์ฌ๋ก๊ฑดยท๋ธ๋๋ ๋ค์์ด ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ๋ผ์ผ ํ๋ค. "
|
79 |
+
"๋ฐฐ์ด์ ์ต๊ณ ์ ์ ์์ด index 0, ๊ทธ๋ค์์ด index 1 โฆ 9 ์์์ฌ์ผ ํ๋ค. "
|
80 |
+
"๊ฒฐ๊ณผ๋ JSON ์ธ ๋ค๋ฅธ ํ
์คํธ๋ฅผ ํฌํจํ๋ฉด ์ ๋๋ค."
|
81 |
)
|
82 |
|
83 |
|
84 |
+
def call_llm(seed: str):
|
|
|
85 |
resp = client.chat.completions.create(
|
86 |
+
model="gpt-4o-mini",
|
87 |
messages=[
|
88 |
{"role": "system", "content": SYSTEM_PROMPT},
|
89 |
{"role": "user", "content": seed},
|
90 |
],
|
91 |
temperature=0.9,
|
92 |
+
max_tokens=1024,
|
93 |
)
|
94 |
raw = resp.choices[0].message.content.strip()
|
|
|
|
|
95 |
try:
|
96 |
data = json.loads(raw)
|
97 |
+
if not isinstance(data, list) or len(data) != 10:
|
98 |
+
raise ValueError("JSON ๋ฐฐ์ด ๊ธธ์ด๊ฐ 10์ด ์๋")
|
99 |
+
except Exception as exc:
|
100 |
+
raise ValueError(f"LLM JSON ํ์ฑ ์คํจ: {exc}\n์๋ฌธ: {raw[:300]} โฆ")
|
101 |
return data
|
102 |
|
103 |
# -------------------------------------------------
|
104 |
+
# 4. Gradio callback
|
105 |
# -------------------------------------------------
|
106 |
|
107 |
+
def generate(seed_word: str):
|
108 |
+
results = call_llm(seed_word)
|
109 |
+
# 1์ ๋์
|
110 |
+
fig = draw_square({k: results[0][k] for k in ("tl", "tr", "br", "bl")})
|
111 |
+
|
112 |
+
# ๋ฆฌ์คํธ ๋งํฌ๋ค์ด
|
113 |
+
md_lines = []
|
114 |
+
for idx, item in enumerate(results, 1):
|
115 |
+
md_lines.append(
|
116 |
+
f"### {idx}. {item['top_phrase']} / {item['bottom_phrase']}\n"
|
117 |
+
f"- **์ฌ๋ก๊ฑด**: {item['slogan']}\n"
|
118 |
+
f"- **๋ธ๋๋ ๋ค์**: {item['brand']}\n"
|
119 |
+
f"- (tl={item['tl']}, tr={item['tr']}, br={item['br']}, bl={item['bl']})\n"
|
120 |
+
)
|
121 |
+
markdown_out = "\n".join(md_lines)
|
122 |
+
return fig, markdown_out
|
123 |
|
124 |
# -------------------------------------------------
|
125 |
+
# 5. UI
|
126 |
# -------------------------------------------------
|
127 |
+
with gr.Blocks(title="Square Theory โ Topย 10 ๐ฐ๐ท") as demo:
|
128 |
+
gr.Markdown("""# ๐ Square Theory ์ ์ Topย 10\n๋จ์ด 1๊ฐ โ LLM์ด ํ๊ฐยท์ ๋ ฌํ 10๊ฐ ์ฌ๊ฐํ/์นดํผ/๋ธ๋๋ ๋ค์""")
|
129 |
seed = gr.Textbox(label="์๋ ๋จ์ด(TL)", placeholder="์: ๊ณจ๋ ")
|
130 |
+
run = gr.Button("์์ฑ")
|
131 |
+
fig_out = gr.Plot(label="1์ ์ฌ๊ฐํ")
|
132 |
+
md_out = gr.Markdown(label="Topย 10 ์ ์")
|
133 |
+
|
134 |
+
run.click(generate, inputs=seed, outputs=[fig_out, md_out])
|
|
|
|
|
|
|
135 |
|
136 |
if __name__ == "__main__":
|
137 |
demo.launch()
|