Spaces:
Runtime error
Runtime error
import os | |
import gradio as gr | |
import random | |
import time | |
import logging | |
import google.generativeai as genai | |
# λ‘κΉ μ€μ | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | |
handlers=[ | |
logging.FileHandler("api_debug.log"), | |
logging.StreamHandler() | |
] | |
) | |
logger = logging.getLogger("idea_generator") | |
# Gemini API ν€λ νκ²½ λ³μ GEMINI_API_KEYμμ κ°μ Έμ΅λλ€. | |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") | |
genai.configure(api_key=GEMINI_API_KEY) | |
# μ¬λμ("/")κ° ν¬ν¨λ λ³ν λ¬Έμμ΄μμ λ μ΅μ μ€ νλλ§ μ ννλ ν¬νΌ ν¨μ | |
def choose_alternative(transformation): | |
if "/" not in transformation: | |
return transformation | |
parts = transformation.split("/") | |
if len(parts) != 2: | |
return random.choice([part.strip() for part in parts]) | |
left = parts[0].strip() | |
right = parts[1].strip() | |
if " " in left: | |
tokens = left.split(" ", 1) | |
prefix = tokens[0] | |
if not right.startswith(prefix): | |
option1 = left | |
option2 = prefix + " " + right | |
else: | |
option1 = left | |
option2 = right | |
return random.choice([option1, option2]) | |
else: | |
return random.choice([left, right]) | |
# μ°½μμ μΈ λͺ¨λΈ/컨μ /νμ λ³ν μμ΄λμ΄λ₯Ό μν μΉ΄ν κ³ λ¦¬ (κΈ°μ‘΄ '물리μ λ³ν' μ¬μ μ μ§) | |
physical_transformation_categories = { | |
"곡κ°μ λ³ν": [ | |
"μ μ§/νμ§ μ΄λ", "μ’/μ° μ΄λ", "μμΉ/νκ°", "νΌμΉ νμ ", "μ νμ ", "λ‘€ νμ ", | |
"κΆ€λ μ΄λ", "λμ ν μ΄λ", "κ΄μ± λ리ννΈ", "μμ΄λ‘μ€μ½ν½ μΈμ°¨ μ΄λ", "λΉλμΉ νμ ", | |
"μ§μ μ΄λ", "νλνμ μ΄λ", "무μ€λ ₯ μνμμμ λΆμ " | |
], | |
"물리μ νμ λ³ν": [ | |
"λΆνΌ μ¦κ°/κ°μ", "κΈΈμ΄ μ μ₯/μμΆ", "λλΉ νμ₯/μΆμ", "λμ΄ μ¦κ°/κ°μ", | |
"λ°λ λ³ν", "λ¬΄κ² μ¦κ°/κ°μ", "νν λ³ν", "μμ λ³ν", "λΉλ±λ°©μ± λ³ν", | |
"λΉμ ν λ³ν", "λ€νλ¦Ό/λΉνλ¦Ό", "μμΆ/ν½μ°½ λΉμ¨ λ³ν", "λͺ¨μ리 λΌμ΄λ©/μ€νλ", | |
"νλ¨/κ· μ΄ μ§ν", "μΈκ·Έλ¨ΌνΈν" | |
], | |
"νλ©΄/μΈκ΄ λ³ν": [ | |
"μμ λ³ν", "ν μ€μ² λ³ν", "ν¬λͺ λ/λΆν¬λͺ λ λ³ν", "κ΄ν/λ¬΄κ΄ λ³ν", | |
"λ°μ¬μ¨ λ³ν", "ν¨ν΄ λ³ν", "μ΄μμ± ν¨κ³Ό", "κ΄λ³μ ν¨κ³Ό", "μ΄λ³μ ν¨κ³Ό", | |
"νλ‘κ·Έλν½ ν¨ν΄ λ³ν", "νλ λ¬ λ°μ¬", "νλ©΄ λͺ¨ν", "λλ Έκ΅¬μ‘° ν¨ν΄ λ³ν", | |
"μκ° μ²μ ν¨κ³Ό" | |
], | |
"λ¬Όμ§ μν λ³ν": [ | |
"κ³ μ²΄ν/μ‘ν/κΈ°ν", "κ²°μ ν/μ©ν΄", "μ°ν/λΆμ", "κ²½ν/μ°ν", "μ΄μκ³ μν μ ν", | |
"λΉμ μ§ν/κ²°μ ν", "μλΆλ¦¬", "μ½λ‘μ΄λ νμ±/λΆν΄", "κ²ν/μ‘Έν", "μ€μμ μν μ μ΄", | |
"μ기쑰립/λΆν΄", "μμ μ΄ νμ€ν 리μμ€", "μ΅ν΄", "μκ³ " | |
], | |
"μ΄μνμ λ³ν": [ | |
"μ¨λ μμΉ/λκ°", "μ΄ν½μ°½/μμΆ", "μ΄ μ λ/λ¨μ΄", "μλ ₯ μ¦κ°/κ°μ", "λ¨μ΄ μν/νμν", | |
"μνΈλ‘νΌ λ³ν", "μ΄μ κΈ° ν¨κ³Ό", "μκΈ°μ΄λ ν¨κ³Ό", "μλ³ν μΆμ΄/λ°©μ΄", "μ΄ μ€νΈλ μ€ λ°μ/μν", | |
"μ΄μΆ©κ²© ν¨κ³Ό", "λ³΅μ¬ λκ°/κ°μ΄" | |
], | |
"μ΄λνμ λ³ν": [ | |
"κ°μ/κ°μ", "λ±μ μ΄λ", "μ§λ/μ§λ κ°μ ", "μΆ©λ/λ°λ°", "νμ μλ μ¦κ°/κ°μ", | |
"κ°μλ λ³ν", "μΉ΄μ€μ€μ μ΄λ", "μ€ν±-μ¬λ¦½ νμ", "곡μ§/λ°κ³΅μ§", "μ 체μνμ μλ ₯/νλ ₯ λ³ν", | |
"λν κ³μ λ³ν", "νλͺ¨λ λͺ¨μ ν©μ±", "λΉλ΄ν΄ μ 체 κ±°λ", "νμ -λ³μ§ μ΄λ 컀νλ§" | |
], | |
"ꡬ쑰μ λ³ν": [ | |
"λΆν μΆκ°/μ κ±°", "쑰립/λΆν΄", "μ μ΄/νΌμΉ¨", "λ³ν/볡μ", "μμμ΅μ ν νμ λ³ν", | |
"μκ° μ¬κ΅¬μ±", "νλν ν¨ν΄ νμ±/μλ©Έ", "μΈν¬μλμ ν¨ν΄ λ³ν", "λͺ¨λμ λ³ν", | |
"λ°νμ ꡬ쑰 νμ±", "νμ κΈ°μ΅ ν¨κ³Ό", "4D νλ¦°ν ꡬ쑰 λ³ν", "λΆλΆ μ κ±°", "λΆλΆ κ΅ν", | |
"κ²°ν©", "λΆλ¦¬" | |
], | |
"μ κΈ°/μκΈ°μ λ³ν": [ | |
"μν/νμν", "μ ν μ¦κ°/κ°μ", "μ κΈ°μ₯ μμ±/μλ©Έ", "μκΈ°μ₯ μμ±/μλ©Έ", "μ΄μ λ μν μ μ΄", | |
"κ°μ μ /λ°κ°μ μ μ μ΄", "μμ μ€ν μν λ³ν", "νλΌμ¦λ§ μν νμ±/μλ©Έ", "μ€νν μ ν", | |
"κ΄μ ν¨κ³Ό", "μμ ν¨κ³Ό", "ν ν¨κ³Ό" | |
], | |
"ννμ λ³ν": [ | |
"νλ©΄ μ½ν λ³ν", "λ¬Όμ§ μ‘°μ± λ³ν", "νν λ°μμ μν λ³ν", "μ΄λ§€ νμ±ν/λΉνμ±ν", | |
"κ΄νν λ°μ", "μ κΈ°νν λ°μ", "μ기쑰립 λ¨λΆμλ§ νμ±", "λΆμμ»΄ν¨ν λ³ν", | |
"μ체λͺ¨λ°© νλ©΄ λ³ν", "μ€λ§νΈ ν΄λ¦¬λ¨Έ λ°μ", "ννμ μ§λ λ°μ", "μ°ν", "νμ", | |
"μ€ν©", "κ°μλΆν΄", "μ΅ν©", "λ°©μ¬ν" | |
], | |
"μκ° κ΄λ ¨ λ³ν": [ | |
"λ Έν/νν", "λ§λͺ¨/λΆμ", "ν΄μ/λ³μ", "μμ/볡ꡬ", "μλͺ μ£ΌκΈ° λ¨κ³ λ³ν", | |
"μ¬μ©μ μΈν°λμ κΈ°λ° μ μ", "νμ΅κΈ°λ° νμ μ΅μ ν", "μκ°μ λ¬Όμ± λ³ν", "μ§λ¨ κΈ°μ΅ ν¨κ³Ό", | |
"λ¬Ένμ μλ―Έ λ³ν", "μκ° μ§μ° μλ΅", "μ΄λ ₯ μμ‘΄μ λ³ν", "νΌμ§ μκ° κ±°λ", "μ§νμ λ³ν", | |
"μ£ΌκΈ°μ μ¬μ/μ¬μμ±" | |
] | |
} | |
############################################################################## | |
# Gemini API νΈμΆ ν¨μ (μ: gemini-2.0-flash-thinking-exp-01-21 -> λ€λ₯Έ λͺ¨λΈ μ¬μ© μ μμ ) | |
############################################################################## | |
def query_gemini_api(prompt): | |
try: | |
# μμ: κΈ°μ‘΄ gemini-2.0... λμ , λ€λ₯Έ λͺ¨λΈμ΄ νμνλ€λ©΄ κ΅μ²΄νμΈμ. | |
model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21') | |
response = model.generate_content(prompt) | |
# μλ΅ κ΅¬μ‘° λ°©μ΄μ μΌλ‘ μ²λ¦¬ | |
try: | |
if hasattr(response, 'text'): | |
return response.text | |
if hasattr(response, 'candidates') and response.candidates: | |
if len(response.candidates) > 0: | |
candidate = response.candidates[0] | |
if hasattr(candidate, 'content'): | |
content = candidate.content | |
if hasattr(content, 'parts') and content.parts: | |
if len(content.parts) > 0: | |
return content.parts[0].text | |
if hasattr(response, 'parts') and response.parts: | |
if len(response.parts) > 0: | |
return response.parts[0].text | |
return "Unable to generate a response. API response structure is different than expected." | |
except Exception as inner_e: | |
logger.error(f"Error processing response: {inner_e}") | |
return f"An error occurred while processing the response: {str(inner_e)}" | |
except Exception as e: | |
logger.error(f"Error calling Gemini API: {e}") | |
if "API key not valid" in str(e): | |
return "API key is not valid. Please check your GEMINI_API_KEY environment variable." | |
return f"An error occurred while calling the API: {str(e)}" | |
############################################################################## | |
# μ€λͺ νμ₯ ν¨μ: "λͺ¨λΈ/컨μ /νμμ λ³νμ λν μ΄ν΄μ νμ ν¬μΈνΈ, κΈ°λ₯μ± λ±μ μ€μ¬"μΌλ‘ | |
############################################################################## | |
def enhance_with_llm(base_description, obj_name, category): | |
prompt = f""" | |
λ€μμ '{obj_name}'μ '{category}' κ΄λ ¨ κ°λ¨ν μ€λͺ μ λλ€: | |
"{base_description}" | |
μ λ΄μ©μ λ³΄λ€ κ΅¬μ²΄ννμ¬, | |
1) μ°½μμ μΈ λͺ¨λΈ/컨μ /νμμ λ³νμ λν μ΄ν΄, | |
2) νμ ν¬μΈνΈμ κΈ°λ₯μ± λ±μ μ€μ¬μΌλ‘ | |
3~4λ¬Έμ₯μ μμ΄λμ΄λ‘ νμ₯ν΄ μ£ΌμΈμ. | |
""" | |
return query_gemini_api(prompt) | |
############################################################################## | |
# λ¨μΌ ν€μλ(μ€λΈμ νΈ)μ λν "μ°½μμ λ³ν μμ΄λμ΄" μμ± | |
############################################################################## | |
def generate_single_object_transformations(obj): | |
results = {} | |
for category, transformations in physical_transformation_categories.items(): | |
transformation = choose_alternative(random.choice(transformations)) | |
base_description = f"{obj}μ΄(κ°) {transformation} νμμ 보μΈλ€" | |
results[category] = {"base": base_description, "enhanced": None} | |
return results | |
############################################################################## | |
# λ ν€μλμ λν "μ°½μμ λ³ν μμ΄λμ΄" μμ± | |
############################################################################## | |
def generate_two_objects_interaction(obj1, obj2): | |
results = {} | |
for category, transformations in physical_transformation_categories.items(): | |
transformation = choose_alternative(random.choice(transformations)) | |
template = random.choice([ | |
"{obj1}μ΄(κ°) {obj2}μ κ²°ν©νμ¬ {change}κ° λ°μνλ€", | |
"{obj1}κ³Ό(μ) {obj2}μ΄(κ°) μΆ©λνλ©΄μ {change}κ° μΌμ΄λ¬λ€" | |
]) | |
base_description = template.format(obj1=obj1, obj2=obj2, change=transformation) | |
results[category] = {"base": base_description, "enhanced": None} | |
return results | |
############################################################################## | |
# μΈ ν€μλμ λν "μ°½μμ λ³ν μμ΄λμ΄" μμ± | |
############################################################################## | |
def generate_three_objects_interaction(obj1, obj2, obj3): | |
results = {} | |
for category, transformations in physical_transformation_categories.items(): | |
transformation = choose_alternative(random.choice(transformations)) | |
template = random.choice([ | |
"{obj1}, {obj2}, {obj3}μ΄(κ°) μΌκ°ν κ΅¬μ‘°λ‘ κ²°ν©νμ¬ {change}κ° λ°μνλ€", | |
"{obj1}μ΄(κ°) {obj2}μ(κ³Ό) {obj3} μ¬μ΄μμ λ§€κ°μ²΄ μν μ νλ©° {change}λ₯Ό μ΄μ§νλ€" | |
]) | |
base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation) | |
results[category] = {"base": base_description, "enhanced": None} | |
return results | |
############################################################################## | |
# μμ±λ κΈ°λ³Έ μ€λͺ μ LLMμ ν΅ν΄ νμ₯ | |
############################################################################## | |
def enhance_descriptions(results, objects): | |
obj_name = " λ° ".join([obj for obj in objects if obj]) | |
for category, result in results.items(): | |
result["enhanced"] = enhance_with_llm(result["base"], obj_name, category) | |
return results | |
############################################################################## | |
# μ¬μ©μ μ λ ₯(μ΅λ 3κ° ν€μλ)μ λ°λΌ μ°½μμ λ³ν μμ΄λμ΄ μμ± | |
############################################################################## | |
def generate_transformations(text1, text2=None, text3=None): | |
if text2 and text3: | |
results = generate_three_objects_interaction(text1, text2, text3) | |
objects = [text1, text2, text3] | |
elif text2: | |
results = generate_two_objects_interaction(text1, text2) | |
objects = [text1, text2] | |
else: | |
results = generate_single_object_transformations(text1) | |
objects = [text1] | |
return enhance_descriptions(results, objects) | |
############################################################################## | |
# κ²°κ³Ό ν¬λ§·ν | |
############################################################################## | |
def format_results(results): | |
formatted = "" | |
for category, result in results.items(): | |
formatted += f"## {category}\n**κΈ°λ³Έ μμ΄λμ΄**: {result['base']}\n\n**νμ₯λ μμ΄λμ΄**: {result['enhanced']}\n\n---\n\n" | |
return formatted | |
############################################################################## | |
# Gradio UIμμ νΈμΆν ν¨μ | |
############################################################################## | |
def process_inputs(text1, text2, text3): | |
messages = [] | |
messages.append("μ λ ₯κ° νμΈ μ€...") | |
time.sleep(0.3) | |
text1 = text1.strip() if text1 else None | |
text2 = text2.strip() if text2 else None | |
text3 = text3.strip() if text3 else None | |
if not text1: | |
messages.append("μ€λ₯: μ΅μ νλμ ν€μλλ₯Ό μ λ ₯ν΄μ£ΌμΈμ.") | |
return "\n\n".join(messages) | |
messages.append("μ°½μμ μΈ λͺ¨λΈ/컨μ /νμ λ³ν μμ΄λμ΄ μμ± μ€...") | |
time.sleep(0.3) | |
results = generate_transformations(text1, text2, text3) | |
messages.append("κ²°κ³Ό ν¬λ§·ν μ€...") | |
time.sleep(0.3) | |
formatted = format_results(results) | |
messages.append("μλ£!") | |
messages.append(formatted) | |
return "\n\n".join(messages) | |
############################################################################## | |
# API ν€ κ²½κ³ λ©μμ§ | |
############################################################################## | |
def get_warning_message(): | |
if not GEMINI_API_KEY: | |
return "β οΈ νκ²½ λ³μ GEMINI_API_KEYκ° μ€μ λμ§ μμμ΅λλ€. Gemini API ν€λ₯Ό μ€μ νμΈμ." | |
return "" | |
############################################################################## | |
# Gradio UI | |
############################################################################## | |
with gr.Blocks(title="ν€μλ κΈ°λ° μ°½μμ λ³ν μμ΄λμ΄ μμ±κΈ°", | |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo: | |
gr.HTML(""" | |
<style> | |
body { background: linear-gradient(135deg, #e0eafc, #cfdef3); font-family: 'Arial', sans-serif; } | |
.gradio-container { padding: 20px; } | |
h1, h2 { text-align: center; } | |
h1 { color: #333; } | |
h2 { color: #555; } | |
.output { background-color: #ffffff; padding: 15px; border-radius: 8px; } | |
.gr-button { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 8px 16px; } | |
</style> | |
""") | |
gr.Markdown("# π ν€μλ κΈ°λ° μ°½μμ λ³ν μμ΄λμ΄ μμ±κΈ°") | |
gr.Markdown("μ λ ₯ν **ν€μλ**(μ΅λ 3κ°)λ₯Ό λ°νμΌλ‘, **μ°½μμ μΈ λͺ¨λΈ/컨μ /νμ λ³ν**μ λν μ΄ν΄μ **νμ ν¬μΈνΈ**, **κΈ°λ₯μ±** λ±μ μ€μ¬μΌλ‘ νμ₯λ μμ΄λμ΄λ₯Ό μ μν©λλ€.") | |
warning = gr.Markdown(get_warning_message()) | |
# μ’μΈ‘ μ λ ₯ μμ | |
with gr.Row(): | |
with gr.Column(scale=1): | |
text_input1 = gr.Textbox(label="ν€μλ 1 (νμ)", placeholder="μ: μ€λ§νΈν°") | |
text_input2 = gr.Textbox(label="ν€μλ 2 (μ ν)", placeholder="μ: μΈκ³΅μ§λ₯") | |
text_input3 = gr.Textbox(label="ν€μλ 3 (μ ν)", placeholder="μ: ν¬μ€μΌμ΄") | |
submit_button = gr.Button("μμ΄λμ΄ μμ±νκΈ°") | |
# μ°μΈ‘ μΆλ ₯ μμ (νμ νλλ§ μ¬μ©) | |
with gr.Column(scale=2): | |
with gr.TabItem("μ°½μμ μΈ λͺ¨λΈ/컨μ /νμ λ³ν μμ΄λμ΄", id="creative_tab"): | |
idea_output = gr.Markdown(label="μμ΄λμ΄ κ²°κ³Ό") | |
# μμ μ λ ₯ | |
gr.Examples( | |
examples=[ | |
["μ€λ§νΈν°", "", ""], | |
["컀νΌ", "μ± ", ""], | |
["μλμ°¨", "λ‘λ΄", "μΈκ³΅μ§λ₯"], | |
["μ΄λν", "μ¨μ΄λ¬λΈ", "건κ°"], | |
], | |
inputs=[text_input1, text_input2, text_input3], | |
) | |
# λ²νΌ μ΄λ²€νΈ: 첫 λ²μ§Έ νμλ§ μ°κ²° | |
submit_button.click(fn=process_inputs, | |
inputs=[text_input1, text_input2, text_input3], | |
outputs=idea_output) | |
if __name__ == "__main__": | |
demo.launch(debug=True) | |