benjamin5607 commited on
Commit
fbd0c37
ยท
verified ยท
1 Parent(s): 84daabb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -57
app.py CHANGED
@@ -1,112 +1,78 @@
1
  import gradio as gr
2
- from google import genai # ์‹ ํ˜• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ
3
  import edge_tts
4
- import asyncio
5
  import os
6
 
7
- # 1. ์‹ ํ˜• ๊ตฌ๊ธ€ ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ
8
- # (API ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ)
9
  GENAI_KEY = os.getenv("GEMINI_KEY")
10
  client = genai.Client(api_key=GENAI_KEY)
11
 
12
- # 2. ๋ฉค๋ฒ„๋ณ„ ํŽ˜๋ฅด์†Œ๋‚˜(์„ฑ๊ฒฉ) & ๋ชฉ์†Œ๋ฆฌ ์„ค์ • (๊ธฐ์กด๊ณผ ๋™์ผ)
13
  MEMBERS = {
14
  "์„œ์œค (Korea)": {
15
  "role": "๋ฉ”์ธ ๋ณด์ปฌ",
16
  "voice": "ko-KR-SunHiNeural",
17
- "prompt": """๋‹น์‹ ์€ ๋ก๋ฐด๋“œ 'Error 404'์˜ ๋ฉ”์ธ๋ณด์ปฌ '์„œ์œค'์ž…๋‹ˆ๋‹ค.
18
- ํ•œ๊ตญ์–ด(Korean)๋กœ ๋Œ€๋‹ตํ•˜์„ธ์š”.
19
- ์„ฑ๊ฒฉ: ์‹œ๋‹ˆ์ปฌํ•˜์ง€๋งŒ ์†์€ ๋”ฐ๋œปํ•จ. '์•ผ', '์žˆ์ž–์•„' ๊ฐ™์€ ๊ตฌ์–ด์ฒด๋ฅผ ์”€.
20
- ์—ญํ• : ์‚ฌ์šฉ์ž์˜ ๊ณ ๋ฏผ์„ ๋“ฃ๊ณ  ๊ฐ€์‚ฌ(Lyrics)์— ๋น—๋Œ€์–ด ํ•ด๊ฒฐ์ฑ…์„ ์คŒ.
21
- ๋งํˆฌ ์˜ˆ์‹œ: "์•ผ, ๊ฐ€์‚ฌ๊ฐ€ ๋ง‰ํ˜”์–ด? ๊ทธ๋ƒฅ ์งˆ๋Ÿฌ๋ณด๋Š” ๊ฑฐ์•ผ. ๋„ค ๋งˆ์Œ์ด ์‹œํ‚ค๋Š” ๋Œ€๋กœ." """
22
  },
23
  "Chloe (USA)": {
24
  "role": "๋ฆฌ๋“œ ๊ธฐํƒ€",
25
  "voice": "en-US-AriaNeural",
26
- "prompt": """You are 'Chloe', the lead guitarist of the rock band 'Error 404'.
27
- Respond in English.
28
- Personality: Energetic, cool, confident rockstar.
29
- Role: Give advice using guitar metaphors (riffs, distortion, tension).
30
- Tone: "Hey! Pump up the volume! Don't be afraid to break the rules." """
31
  },
32
  "Beatrice (Brazil)": {
33
  "role": "๋“œ๋Ÿผ",
34
  "voice": "pt-BR-FranciscaNeural",
35
- "prompt": """You are 'Beatrice', the drummer from Brazil.
36
- Respond in English (mixed with some Portuguese words like 'Vamos', 'Amigo').
37
- Personality: Passionate, loud, high energy.
38
- Role: Focus on rhythm, beat, and heart pounding.
39
- Tone: "Vamos! Feel the beat! Smash that kick drum!" """
40
  },
41
  "Naomi (Japan)": {
42
  "role": "๋ฆฌ๋“ฌ ๊ธฐํƒ€",
43
  "voice": "ja-JP-NanamiNeural",
44
- "prompt": """You are 'Naomi', the rhythm guitarist from Japan.
45
- Respond in Japanese (and a little English).
46
- Personality: Calm, mysterious, professional.
47
- Role: Focus on stability, backbone, and harmony.
48
- Tone: "ๅคงไธˆๅคซ (It's okay). Rhythm is the foundation. Keep it steady." """
49
  },
50
  "Elena (Spain)": {
51
  "role": "๋ฒ ์ด์Šค",
52
  "voice": "es-ES-ElviraNeural",
53
- "prompt": """You are 'Elena', the bassist from Spain.
54
- Respond in Spanish (mixed with English).
55
- Personality: Sexy, mature, deep voice.
56
- Role: Focus on groove, low-end, and grounding.
57
- Tone: "Hola. Feel the bass. Deep inside your soul." """
58
  },
59
  "Amira (Egypt)": {
60
  "role": "ํ‚ค๋ณด๋“œ",
61
  "voice": "ar-EG-SalmaNeural",
62
- "prompt": """You are 'Amira', the keyboardist from Egypt.
63
- Respond in Arabic (mixed with English).
64
- Personality: Dreamy, mystical, wise.
65
- Role: Focus on atmosphere, melody, and magic.
66
- Tone: "Salam. Like a desert wind... create a melody." """
67
  },
68
  "Liwei (China)": {
69
  "role": "DJ / FX",
70
  "voice": "zh-CN-XiaoxiaoNeural",
71
- "prompt": """You are 'Liwei', the DJ/FX from China.
72
- Respond in Chinese (mixed with English).
73
- Personality: Trendy, tech-savvy, Gen-Z hacker.
74
- Role: Focus on glitch, noise, trend, and remix.
75
- Tone: "ๅฌ็€ (Listen)! Glitch is art. Make it trendy." """
76
  },
77
  "Sophie (France)": {
78
  "role": "๋ฐ”์ด์˜ฌ๋ฆฐ",
79
  "voice": "fr-FR-DeniseNeural",
80
- "prompt": """You are 'Sophie', the violinist from France.
81
- Respond in French (mixed with English).
82
- Personality: Elegant, artistic, slightly arrogant but charming.
83
- Role: Focus on beauty, strings, and elegance.
84
- Tone: "C'est magnifique. Add some strings, chรฉri." """
85
  }
86
  }
87
 
88
  async def band_consulting(user_input, member_name):
89
  try:
 
90
  if member_name not in MEMBERS:
91
- # ์ด๋ฆ„ ๋ถˆ์ผ์น˜ ์‹œ ๋””๋ฒ„๊น…์šฉ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
92
- return f"Error: ์ด๋ฆ„์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค! ๋ฐ›์€ ์ด๋ฆ„: '{member_name}'", None
93
 
94
  member = MEMBERS[member_name]
95
 
96
- # [Step 1] ๋‡Œ: ์‹ ํ˜• ๊ตฌ๊ธ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ
97
  chat_prompt = f"{member['prompt']}\n\nUser's Error/Worry: {user_input}\nResponse:"
98
 
99
  try:
100
- # ๋ฌธ๋ฒ•์ด ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค: client.models.generate_content
101
  response = client.models.generate_content(
102
- model='gemini-1.5-flash',
103
  contents=chat_prompt
104
  )
105
  ai_text = response.text
106
  except Exception as e:
107
  return f"Error (Gemini): {str(e)}", None
108
 
109
- # [Step 2] ์ž…: ์—ฃ์ง€TTS
110
  try:
111
  output_file = f"/tmp/{member_name}_reply.mp3"
112
  communicate = edge_tts.Communicate(ai_text, member['voice'])
@@ -119,21 +85,17 @@ async def band_consulting(user_input, member_name):
119
  except Exception as e:
120
  return f"System Error: {str(e)}", None
121
 
122
-
123
- # Blocks ๋ฐฉ์‹์œผ๋กœ UI ๊ตฌ์„ฑ (API ์ด๋ฆ„ ๊ฐ•์ œ ์ง€์ •)
124
  with gr.Blocks() as demo:
125
  gr.Markdown("# Error 404 Band API Server")
126
-
127
  with gr.Row():
128
  inp_text = gr.Textbox(label="๊ณ ๋ฏผ ์ž…๋ ฅ")
129
  inp_member = gr.Dropdown(choices=list(MEMBERS.keys()), label="๋ฉค๋ฒ„ ์„ ํƒ", value="์„œ์œค (Korea)")
130
-
131
  out_text = gr.Textbox(label="์กฐ์–ธ")
132
  out_audio = gr.Audio(label="์Œ์„ฑ")
133
-
134
  btn = gr.Button("์ƒ๋‹ด ์š”์ฒญ")
135
 
136
- # api_name="predict" ์ง€์ • ํ•„์ˆ˜!
137
  btn.click(fn=band_consulting, inputs=[inp_text, inp_member], outputs=[out_text, out_audio], api_name="predict")
138
 
139
  demo.launch()
 
1
  import gradio as gr
2
+ from google import genai # ๋ฐ˜๋“œ์‹œ requirements.txt์— google-genai๊ฐ€ ์žˆ์–ด์•ผ ํ•จ
3
  import edge_tts
 
4
  import os
5
 
6
+ # 1. API ํ‚ค ์„ค์ •
 
7
  GENAI_KEY = os.getenv("GEMINI_KEY")
8
  client = genai.Client(api_key=GENAI_KEY)
9
 
10
+ # 2. ๋ฉค๋ฒ„ ๋ฐ์ดํ„ฐ
11
  MEMBERS = {
12
  "์„œ์œค (Korea)": {
13
  "role": "๋ฉ”์ธ ๋ณด์ปฌ",
14
  "voice": "ko-KR-SunHiNeural",
15
+ "prompt": "๋‹น์‹ ์€ ๋ก๋ฐด๋“œ 'Error 404'์˜ ๋ฉ”์ธ๋ณด์ปฌ '์„œ์œค'์ž…๋‹ˆ๋‹ค. ํ•œ๊ตญ์–ด(Korean)๋กœ ๋Œ€๋‹ตํ•˜์„ธ์š”. ์„ฑ๊ฒฉ: ์‹œ๋‹ˆ์ปฌํ•˜์ง€๋งŒ ์ธค๋ฐ๋ ˆ. ๋งํˆฌ: '์•ผ', '์žˆ์ž–์•„' ๊ฐ™์€ ๊ตฌ์–ด์ฒด ์‚ฌ์šฉ. ์—ญํ• : ๊ณ ๋ฏผ์„ ๊ฐ€์‚ฌ(Lyrics)์— ๋น—๋Œ€์–ด ํ•ด๊ฒฐ."
 
 
 
 
16
  },
17
  "Chloe (USA)": {
18
  "role": "๋ฆฌ๋“œ ๊ธฐํƒ€",
19
  "voice": "en-US-AriaNeural",
20
+ "prompt": "You are 'Chloe', the lead guitarist. Respond in English. Personality: Energetic, cool rockstar. Tone: 'Hey! Pump up the volume!'"
 
 
 
 
21
  },
22
  "Beatrice (Brazil)": {
23
  "role": "๋“œ๋Ÿผ",
24
  "voice": "pt-BR-FranciscaNeural",
25
+ "prompt": "You are 'Beatrice', the drummer from Brazil. Respond in English mixed with Portuguese. Personality: Passionate, loud. Tone: 'Vamos! Feel the beat!'"
 
 
 
 
26
  },
27
  "Naomi (Japan)": {
28
  "role": "๋ฆฌ๋“ฌ ๊ธฐํƒ€",
29
  "voice": "ja-JP-NanamiNeural",
30
+ "prompt": "You are 'Naomi', the rhythm guitarist. Respond in Japanese. Personality: Calm, mysterious. Tone: 'ๅคงไธˆๅคซ (It's okay). Keep it steady.'"
 
 
 
 
31
  },
32
  "Elena (Spain)": {
33
  "role": "๋ฒ ์ด์Šค",
34
  "voice": "es-ES-ElviraNeural",
35
+ "prompt": "You are 'Elena', the bassist. Respond in Spanish mixed with English. Personality: Sexy, mature. Tone: 'Hola. Feel the bass.'"
 
 
 
 
36
  },
37
  "Amira (Egypt)": {
38
  "role": "ํ‚ค๋ณด๋“œ",
39
  "voice": "ar-EG-SalmaNeural",
40
+ "prompt": "You are 'Amira', the keyboardist. Respond in Arabic mixed with English. Personality: Dreamy, mystical. Tone: 'Salam. Like a desert wind...'"
 
 
 
 
41
  },
42
  "Liwei (China)": {
43
  "role": "DJ / FX",
44
  "voice": "zh-CN-XiaoxiaoNeural",
45
+ "prompt": "You are 'Liwei', the DJ. Respond in Chinese mixed with English. Personality: Trendy Gen-Z. Tone: 'ๅฌ็€ (Listen)! Glitch is art.'"
 
 
 
 
46
  },
47
  "Sophie (France)": {
48
  "role": "๋ฐ”์ด์˜ฌ๋ฆฐ",
49
  "voice": "fr-FR-DeniseNeural",
50
+ "prompt": "You are 'Sophie', the violinist. Respond in French mixed with English. Personality: Elegant, artistic. Tone: 'C'est magnifique.'"
 
 
 
 
51
  }
52
  }
53
 
54
  async def band_consulting(user_input, member_name):
55
  try:
56
+ # ์ด๋ฆ„ ์ฒดํฌ
57
  if member_name not in MEMBERS:
58
+ return f"Error: ์ด๋ฆ„ ๋ถˆ์ผ์น˜! ('{member_name}')", None
 
59
 
60
  member = MEMBERS[member_name]
61
 
62
+ # [Step 1] ๋‡Œ: Gemini 2.0 ํ˜ธ์ถœ (์ตœ์‹  ๋ชจ๋ธ ๋ช…์‹œ!)
63
  chat_prompt = f"{member['prompt']}\n\nUser's Error/Worry: {user_input}\nResponse:"
64
 
65
  try:
66
+ # โ˜… ์—ฌ๊ธฐ๊ฐ€ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค! ๋ชจ๋ธ๋ช…์„ ์ •ํ™•ํžˆ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
67
  response = client.models.generate_content(
68
+ model='gemini-2.0-flash-exp',
69
  contents=chat_prompt
70
  )
71
  ai_text = response.text
72
  except Exception as e:
73
  return f"Error (Gemini): {str(e)}", None
74
 
75
+ # [Step 2] ์ž…: Edge-TTS
76
  try:
77
  output_file = f"/tmp/{member_name}_reply.mp3"
78
  communicate = edge_tts.Communicate(ai_text, member['voice'])
 
85
  except Exception as e:
86
  return f"System Error: {str(e)}", None
87
 
88
+ # Blocks UI ์„ค์ •
 
89
  with gr.Blocks() as demo:
90
  gr.Markdown("# Error 404 Band API Server")
 
91
  with gr.Row():
92
  inp_text = gr.Textbox(label="๊ณ ๋ฏผ ์ž…๋ ฅ")
93
  inp_member = gr.Dropdown(choices=list(MEMBERS.keys()), label="๋ฉค๋ฒ„ ์„ ํƒ", value="์„œ์œค (Korea)")
 
94
  out_text = gr.Textbox(label="์กฐ์–ธ")
95
  out_audio = gr.Audio(label="์Œ์„ฑ")
 
96
  btn = gr.Button("์ƒ๋‹ด ์š”์ฒญ")
97
 
98
+ # API ์ด๋ฆ„ 'predict' ์ง€์ •
99
  btn.click(fn=band_consulting, inputs=[inp_text, inp_member], outputs=[out_text, out_audio], api_name="predict")
100
 
101
  demo.launch()