|
import os |
|
import sys |
|
import logging |
|
import tempfile |
|
import traceback |
|
from typing import List, Tuple, Optional, Any |
|
import gradio as gr |
|
from gradio_client import Client, handle_file |
|
from dotenv import load_dotenv |
|
import time |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
class SafeFormatter(logging.Formatter): |
|
"""API ์๋ํฌ์ธํธ ์ ๋ณด๋ฅผ ๋ก๊ทธ์์ ์ ๊ฑฐํ๋ ์์ ํ ํฌ๋งคํฐ""" |
|
def format(self, record): |
|
|
|
msg = super().format(record) |
|
|
|
if "API_ENDPOINT" in msg or "happydoggg" in msg or "49493h" in msg: |
|
return msg.replace(os.environ.get("API_ENDPOINT", ""), "[API_ENDPOINT_HIDDEN]") |
|
return msg |
|
|
|
|
|
file_handler = logging.FileHandler("app.log") |
|
console_handler = logging.StreamHandler(sys.stdout) |
|
formatter = SafeFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
|
file_handler.setFormatter(formatter) |
|
console_handler.setFormatter(formatter) |
|
|
|
logger = logging.getLogger("image-enhancer-control-tower") |
|
logger.setLevel(logging.INFO) |
|
logger.addHandler(file_handler) |
|
logger.addHandler(console_handler) |
|
|
|
class GradioClientController: |
|
"""ํ๊น
ํ์ด์ค ๊ทธ๋ผ๋์ค API ํด๋ผ์ด์ธํธ ์ปจํธ๋กค๋ฌ""" |
|
|
|
def __init__(self): |
|
self.client = None |
|
self.api_endpoint = None |
|
self.background_options = {} |
|
self._initialize_client() |
|
|
|
def _initialize_client(self): |
|
"""ํด๋ผ์ด์ธํธ ์ด๊ธฐํ (์๋ํฌ์ธํธ ์ ๋ณด๋ ๋ก๊ทธ์ ๋จ๊ธฐ์ง ์์)""" |
|
try: |
|
self.api_endpoint = os.environ.get("API_ENDPOINT") |
|
if not self.api_endpoint: |
|
logger.error("API_ENDPOINT ํ๊ฒฝ ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.") |
|
raise ValueError("API_ENDPOINT ํ๊ฒฝ ๋ณ์๊ฐ ํ์ํฉ๋๋ค.") |
|
|
|
|
|
max_retries = 3 |
|
for attempt in range(max_retries): |
|
try: |
|
self.client = Client(self.api_endpoint) |
|
logger.info("API ํด๋ผ์ด์ธํธ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ด๊ธฐํ๋์์ต๋๋ค.") |
|
|
|
self._load_simple_background() |
|
return |
|
except Exception as e: |
|
if attempt < max_retries - 1: |
|
logger.warning(f"ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์ฌ์๋ {attempt + 1}/{max_retries}") |
|
time.sleep(2) |
|
else: |
|
raise e |
|
|
|
except Exception as e: |
|
logger.error(f"ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์คํจ: {str(e)}") |
|
self.client = None |
|
|
|
def _load_simple_background(self): |
|
"""์ฌํ ๋ฐฐ๊ฒฝ ์ต์
๋ง ๋จผ์ ๋ก๋""" |
|
try: |
|
if self.client: |
|
result = self.client.predict("์ฌํ ๋ฐฐ๊ฒฝ", api_name="/update_dropdowns") |
|
if isinstance(result, (list, tuple)) and len(result) >= 7: |
|
self.background_options["์ฌํ ๋ฐฐ๊ฒฝ"] = result |
|
logger.info("์ฌํ ๋ฐฐ๊ฒฝ ์ต์
๋ก๋ ์๋ฃ") |
|
return result[0] |
|
except Exception as e: |
|
logger.warning(f"์ฌํ ๋ฐฐ๊ฒฝ ์ต์
๋ก๋ ์คํจ: {str(e)}") |
|
return [] |
|
def get_initial_dropdown_data(self, bg_type: str = "์ฌํ ๋ฐฐ๊ฒฝ") -> Tuple: |
|
"""์ด๊ธฐ ๋๋กญ๋ค์ด ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ""" |
|
try: |
|
|
|
if bg_type in self.background_options: |
|
result = self.background_options[bg_type] |
|
logger.info(f"์บ์์์ ์ด๊ธฐ ๋๋กญ๋ค์ด ๋ฐ์ดํฐ ๋ก๋: {bg_type}") |
|
else: |
|
|
|
if self.client: |
|
result = self.client.predict(bg_type, api_name="/update_dropdowns") |
|
self.background_options[bg_type] = result |
|
logger.info(f"API์์ ์ด๊ธฐ ๋๋กญ๋ค์ด ๋ฐ์ดํฐ ๋ก๋: {bg_type}") |
|
else: |
|
logger.error("ํด๋ผ์ด์ธํธ๊ฐ ์ด๊ธฐํ๋์ง ์์") |
|
return tuple([[] for _ in range(7)]) |
|
|
|
|
|
if isinstance(result, (list, tuple)) and len(result) >= 7: |
|
return result[:7] |
|
else: |
|
return tuple([[] for _ in range(7)]) |
|
|
|
except Exception as e: |
|
logger.error(f"์ด๊ธฐ ๋๋กญ๋ค์ด ๋ฐ์ดํฐ ๋ก๋ ์คํจ: {str(e)}") |
|
return tuple([[] for _ in range(7)]) |
|
|
|
def _parse_dropdown_result(self, result): |
|
"""API ์๋ต์์ ์ค์ ์ ํ์ง ๋ฐ์ดํฐ๋ง ์ถ์ถ - ๋จ์ํ""" |
|
try: |
|
logger.info(f"์๋ต ํ์ฑ: {result}") |
|
|
|
|
|
|
|
if isinstance(result, (list, tuple)) and len(result) >= 7: |
|
|
|
return result[:7] |
|
else: |
|
logger.warning(f"์์ํ์ง ๋ชปํ ์๋ต ํ์: {type(result)}, length={len(result) if hasattr(result, '__len__') else 'N/A'}") |
|
return [[] for _ in range(7)] |
|
|
|
except Exception as e: |
|
logger.error(f"๋๋กญ๋ค์ด ๊ฒฐ๊ณผ ํ์ฑ ์ค๋ฅ: {str(e)}") |
|
return [[] for _ in range(7)] |
|
|
|
def get_initial_simple_choices(self) -> list: |
|
"""์ฌํ ๋ฐฐ๊ฒฝ ์ด๊ธฐ ์ ํ์ง - ํ๋์ฝ๋ฉ์ผ๋ก ํ
์คํธ""" |
|
|
|
return [ |
|
'ํ์ดํธ ๊ธฐ๋ณธ', 'ํ์ ํฌํค', '๋ผ์ดํธ ๊ทธ๋ ์ด', '๊ทธ๋ ์ด ๊ทธ๋ผ๋ฐ์ด์
์คํฌํธ๋ผ์ดํธ', |
|
'ํ๋ฆฌ๋ฏธ์ ๋๋ผ๋งํฑ ๋ธ๋', '๋ฅ๋ธ๋ฃจ ์ ๋ฆฌ๋ฐ์ฌ', 'ํ์คํ
๊ทธ๋ผ๋ฐ์ด์
', '์ค์นด์ด๋ธ๋ฃจ ํ์คํ
', |
|
'๋ฒํฐ์๋ก์ฐ ํ์คํ
', '๋ธ๋ฃจ ์์', '๋ ๋ ์์' |
|
] |
|
|
|
def _ensure_client(self) -> bool: |
|
"""ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ์ํ ํ์ธ ๋ฐ ์ฌ์ฐ๊ฒฐ""" |
|
if self.client is None: |
|
logger.info("ํด๋ผ์ด์ธํธ ์ฌ์ฐ๊ฒฐ ์๋") |
|
self._initialize_client() |
|
return self.client is not None |
|
|
|
def update_dropdowns(self, bg_type: str) -> Tuple: |
|
"""๋ฐฐ๊ฒฝ ์ ํ์ ๋ฐ๋ฅธ ๋๋กญ๋ค์ด ์
๋ฐ์ดํธ - ๋จ์ํ""" |
|
try: |
|
logger.info(f"๋๋กญ๋ค์ด ์
๋ฐ์ดํธ: {bg_type}") |
|
|
|
if not self._ensure_client(): |
|
logger.error("ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ์คํจ") |
|
return tuple([gr.update(visible=False) for _ in range(7)]) |
|
|
|
|
|
result = self.client.predict(bg_type, api_name="/update_dropdowns") |
|
logger.info(f"API ์๋ต: {result}") |
|
|
|
|
|
if isinstance(result, (list, tuple)) and len(result) >= 7: |
|
updates = [] |
|
visibility_map = ["์ฌํ ๋ฐฐ๊ฒฝ", "์คํ๋์ค ๋ฐฐ๊ฒฝ", "์์ฐ ํ๊ฒฝ", "์ค๋ด ํ๊ฒฝ", "ํน์๋ฐฐ๊ฒฝ", "์ฃผ์ผ๋ฆฌ", "ํน์ํจ๊ณผ"] |
|
|
|
for i, choices in enumerate(result[:7]): |
|
is_visible = (bg_type == visibility_map[i]) |
|
|
|
if is_visible and isinstance(choices, list) and len(choices) > 0: |
|
logger.info(f"{visibility_map[i]} ๋๋กญ๋ค์ด: {len(choices)}๊ฐ ์ ํ์ง") |
|
updates.append(gr.update( |
|
visible=True, |
|
choices=choices, |
|
value=choices[0], |
|
interactive=True |
|
)) |
|
else: |
|
updates.append(gr.update(visible=False)) |
|
|
|
return tuple(updates) |
|
else: |
|
logger.error(f"์๋ชป๋ API ์๋ต: {result}") |
|
return tuple([gr.update(visible=False) for _ in range(7)]) |
|
|
|
except Exception as e: |
|
logger.error(f"๋๋กญ๋ค์ด ์
๋ฐ์ดํธ ์ค๋ฅ: {str(e)}") |
|
return tuple([gr.update(visible=False) for _ in range(7)]) |
|
|
|
def generate_prompt_only(self, password: str, bg_type: str, simple: str, studio: str, |
|
nature: str, indoor: str, special: str, jewelry: str, |
|
special_effects: str, request_text: str, aspect_ratio: str) -> str: |
|
"""ํ๋กฌํํธ๋ง ์์ฑ""" |
|
try: |
|
if not self._ensure_client(): |
|
return "ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํด์ฃผ์ธ์." |
|
|
|
result = self.client.predict( |
|
password, |
|
bg_type, |
|
simple or "", |
|
studio or "", |
|
nature or "", |
|
indoor or "", |
|
special or "", |
|
jewelry or "", |
|
special_effects or "", |
|
request_text or "", |
|
aspect_ratio, |
|
api_name="/generate_prompt_with_password_check" |
|
) |
|
|
|
logger.info("ํ๋กฌํํธ ์์ฑ ์๋ฃ") |
|
return result if result else "ํ๋กฌํํธ ์์ฑ์ ์คํจํ์ต๋๋ค." |
|
|
|
except Exception as e: |
|
logger.error(f"ํ๋กฌํํธ ์์ฑ ์ค๋ฅ: {str(e)}") |
|
return f"ํ๋กฌํํธ ์์ฑ ์ค๋ฅ: {str(e)}" |
|
|
|
def process_image(self, password: str, image, bg_type: str, simple: str, studio: str, |
|
nature: str, indoor: str, special: str, jewelry: str, special_effects: str, |
|
request_text: str, quality_level: str, aspect_ratio: str, |
|
output_format: str, enable_enhancement: bool) -> Tuple: |
|
"""์ด๋ฏธ์ง ์ฒ๋ฆฌ (ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ) - API ๋ฌธ์์ ์ ํํ ๋งค์นญ""" |
|
temp_path = None |
|
try: |
|
if not self._ensure_client(): |
|
return ([], None, [], None, "", "", "ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํด์ฃผ์ธ์.") |
|
|
|
|
|
if image is None: |
|
return ([], None, [], None, "", "", "์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํด์ฃผ์ธ์.") |
|
|
|
|
|
temp_path = tempfile.mktemp(suffix='.png') |
|
try: |
|
image.save(temp_path, format='PNG') |
|
logger.info(f"์ด๋ฏธ์ง๋ฅผ ์์ ํ์ผ๋ก ์ ์ฅ: {os.path.basename(temp_path)}") |
|
except Exception as e: |
|
logger.error(f"์ด๋ฏธ์ง ์ ์ฅ ์คํจ: {str(e)}") |
|
return ([], None, [], None, "", "", "์ด๋ฏธ์ง ์ ์ฅ์ ์คํจํ์ต๋๋ค. ๋ค๋ฅธ ์ด๋ฏธ์ง๋ฅผ ์๋ํด๋ณด์ธ์.") |
|
|
|
|
|
logger.info("์ด๋ฏธ์ง ์ฒ๋ฆฌ API ํธ์ถ ์์") |
|
result = self.client.predict( |
|
password, |
|
handle_file(temp_path), |
|
bg_type, |
|
simple or "", |
|
studio or "", |
|
nature or "", |
|
indoor or "", |
|
special or "", |
|
jewelry or "", |
|
special_effects or "", |
|
request_text or "", |
|
quality_level, |
|
aspect_ratio, |
|
output_format, |
|
enable_enhancement, |
|
api_name="/check_password" |
|
) |
|
|
|
logger.info("์ด๋ฏธ์ง ์ฒ๋ฆฌ API ํธ์ถ ์๋ฃ") |
|
|
|
|
|
if isinstance(result, (list, tuple)) and len(result) >= 7: |
|
|
|
|
|
return result[:7] |
|
else: |
|
logger.warning(f"API ์๋ต ํ์ ์ด์: type={type(result)}, length={len(result) if hasattr(result, '__len__') else 'N/A'}") |
|
return ([], None, [], None, "", "", "API์์ ์ฌ๋ฐ๋ฅด์ง ์์ ์๋ต์ ๋ฐ์์ต๋๋ค.") |
|
|
|
except Exception as e: |
|
error_msg = str(e) |
|
logger.error(f"์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค๋ฅ: {error_msg}") |
|
|
|
|
|
if "timeout" in error_msg.lower(): |
|
user_error = "์์ฒญ ์ฒ๋ฆฌ ์๊ฐ์ด ์ด๊ณผ๋์์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํด์ฃผ์ธ์." |
|
elif "connection" in error_msg.lower(): |
|
user_error = "์๋ฒ ์ฐ๊ฒฐ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋คํธ์ํฌ ์ํ๋ฅผ ํ์ธํด์ฃผ์ธ์." |
|
elif "unauthorized" in error_msg.lower() or "password" in error_msg.lower(): |
|
user_error = "์ธ์ฆ์ ์คํจํ์ต๋๋ค. ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํด์ฃผ์ธ์." |
|
else: |
|
user_error = f"์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {error_msg}" |
|
|
|
return ([], None, [], None, "", "", user_error) |
|
|
|
finally: |
|
|
|
if temp_path and os.path.exists(temp_path): |
|
try: |
|
os.remove(temp_path) |
|
logger.info("์์ ํ์ผ ์ ๋ฆฌ ์๋ฃ") |
|
except Exception as e: |
|
logger.warning(f"์์ ํ์ผ ์ ๋ฆฌ ์คํจ: {str(e)}") |
|
|
|
|
|
controller = GradioClientController() |
|
|
|
def create_gradio_interface(): |
|
"""Gradio ์ธํฐํ์ด์ค ์์ฑ""" |
|
try: |
|
logger.info("Gradio ์ธํฐํ์ด์ค ์์ฑ ์์") |
|
|
|
|
|
background_types = ["์ฌํ ๋ฐฐ๊ฒฝ", "์คํ๋์ค ๋ฐฐ๊ฒฝ", "์์ฐ ํ๊ฒฝ", "์ค๋ด ํ๊ฒฝ", "ํน์๋ฐฐ๊ฒฝ", "์ฃผ์ผ๋ฆฌ", "ํน์ํจ๊ณผ"] |
|
|
|
|
|
css = """ |
|
.gradio-container { |
|
max-width: 1200px !important; |
|
} |
|
""" |
|
|
|
with gr.Blocks(title="AI ์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ", css=css, theme=gr.themes.Soft()) as app: |
|
gr.Markdown("# AI ์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ๋๊ตฌ") |
|
|
|
|
|
password_box = gr.Textbox( |
|
label="๋น๋ฐ๋ฒํธ", |
|
type="password", |
|
placeholder="์ฌ์ฉํ๋ ค๋ฉด ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์", |
|
interactive=True |
|
) |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
|
|
image = gr.Image(label="์ํ ์ด๋ฏธ์ง ์
๋ก๋", type="pil") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
background_type = gr.Radio( |
|
choices=background_types, |
|
label="๋ฐฐ๊ฒฝ ์ ํ", |
|
value="์ฌํ ๋ฐฐ๊ฒฝ" |
|
) |
|
|
|
|
|
simple_dropdown = gr.Dropdown( |
|
choices=controller.get_initial_simple_choices(), |
|
value="ํ์ดํธ ๊ธฐ๋ณธ", |
|
label="์ฌํ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=True, |
|
interactive=True |
|
) |
|
|
|
studio_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="์คํ๋์ค ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
nature_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="์์ฐ ํ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
indoor_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="์ค๋ด ํ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
special_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="ํน์๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
jewelry_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="์ฃผ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
special_effects_dropdown = gr.Dropdown( |
|
choices=[], |
|
label="ํน์ํจ๊ณผ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
|
|
request_text = gr.Textbox( |
|
label="์์ฒญ์ฌํญ", |
|
placeholder="์ํ ์ด๋ฏธ์ง์ ์ ์ฉํ ์คํ์ผ, ๋ถ์๊ธฐ, ํน๋ณ ์์ฒญ์ฌํญ ๋ฑ์ ์
๋ ฅํ์ธ์.", |
|
lines=3 |
|
) |
|
|
|
|
|
quality_level = gr.Radio( |
|
label="ํ์ง ๋ ๋ฒจ", |
|
choices=["gpt", "flux"], |
|
value="flux", |
|
info="GPT: GPT ๋ชจ๋ธ (๊ณ ํ์ง), Flux: Flux ๋ชจ๋ธ (๋น ๋ฅธ ์ฒ๋ฆฌ + ๊ธฐ๋ณธ ํ์ง๊ฐ์ )" |
|
) |
|
|
|
aspect_ratio = gr.Dropdown( |
|
label="์ข
ํก๋น", |
|
choices=["1:1", "3:2", "2:3"], |
|
value="1:1" |
|
) |
|
|
|
output_format = gr.Dropdown( |
|
label="์ด๋ฏธ์ง ํ์", |
|
choices=["jpg", "png"], |
|
value="jpg" |
|
) |
|
|
|
|
|
enable_enhancement = gr.Checkbox( |
|
label="์ถ๊ฐ ํ์ง ๊ฐ์ ", |
|
value=False, |
|
info="GPT: 1ํ ํ์ง๊ฐ์ , Flux: 2์ฐจ ํ์ง๊ฐ์ (๊ธฐ๋ณธ 1ํ + ์ถ๊ฐ 1ํ)" |
|
) |
|
|
|
|
|
generate_prompt_btn = gr.Button("ํ๋กฌํํธ๋ง ์์ฑ", variant="secondary") |
|
|
|
|
|
edit_btn = gr.Button("์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ", variant="primary") |
|
|
|
with gr.Column(): |
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("## ํธ์ง๋ ์ด๋ฏธ์ง") |
|
original_output = gr.Gallery(label="ํธ์ง ๊ฒฐ๊ณผ", preview=True) |
|
original_download = gr.File(label="ํธ์ง ์ด๋ฏธ์ง ๋ค์ด๋ก๋", interactive=False) |
|
|
|
with gr.Column(): |
|
gr.Markdown("## ํ์ง ๊ฐ์ ๋ ์ด๋ฏธ์ง") |
|
enhanced_output = gr.Gallery(label="ํ์ง ๊ฐ์ ๊ฒฐ๊ณผ", preview=True) |
|
enhanced_download = gr.File(label="๊ฐ์ ์ด๋ฏธ์ง ๋ค์ด๋ก๋", interactive=False) |
|
|
|
|
|
prompt_output = gr.Textbox(label="์์ฑ๋ ํ๋กฌํํธ", lines=10, interactive=False) |
|
info = gr.Textbox(label="์ฒ๋ฆฌ ์ ๋ณด", interactive=False) |
|
error = gr.Textbox(label="์ค๋ฅ ๋ฉ์์ง", interactive=False, visible=True) |
|
|
|
|
|
background_type.change( |
|
fn=controller.update_dropdowns, |
|
inputs=[background_type], |
|
outputs=[simple_dropdown, studio_dropdown, nature_dropdown, |
|
indoor_dropdown, special_dropdown, jewelry_dropdown, special_effects_dropdown], |
|
queue=False |
|
) |
|
|
|
|
|
generate_prompt_btn.click( |
|
fn=controller.generate_prompt_only, |
|
inputs=[ |
|
password_box, |
|
background_type, |
|
simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, |
|
jewelry_dropdown, special_effects_dropdown, |
|
request_text, aspect_ratio |
|
], |
|
outputs=[prompt_output] |
|
) |
|
|
|
|
|
edit_btn.click( |
|
fn=controller.process_image, |
|
inputs=[ |
|
password_box, |
|
image, background_type, |
|
simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, |
|
jewelry_dropdown, special_effects_dropdown, |
|
request_text, quality_level, aspect_ratio, output_format, enable_enhancement |
|
], |
|
outputs=[ |
|
original_output, original_download, |
|
enhanced_output, enhanced_download, |
|
prompt_output, info, error |
|
] |
|
) |
|
|
|
|
|
def initialize_all_dropdowns(): |
|
"""๋ชจ๋ ๋๋กญ๋ค์ด์ ์ด๊ธฐํํ๋ ํจ์""" |
|
try: |
|
logger.info("๋๋กญ๋ค์ด ์ด๊ธฐํ ์์") |
|
updates = controller.update_dropdowns("์ฌํ ๋ฐฐ๊ฒฝ") |
|
logger.info("๋๋กญ๋ค์ด ์ด๊ธฐํ ์๋ฃ") |
|
return updates |
|
except Exception as e: |
|
logger.error(f"๋๋กญ๋ค์ด ์ด๊ธฐํ ์คํจ: {str(e)}") |
|
return tuple([gr.update() for _ in range(7)]) |
|
|
|
app.load( |
|
fn=initialize_all_dropdowns, |
|
outputs=[simple_dropdown, studio_dropdown, nature_dropdown, |
|
indoor_dropdown, special_dropdown, jewelry_dropdown, special_effects_dropdown] |
|
) |
|
|
|
logger.info("Gradio ์ธํฐํ์ด์ค ์์ฑ ์๋ฃ") |
|
return app |
|
|
|
except Exception as e: |
|
logger.error(f"Gradio ์ธํฐํ์ด์ค ์์ฑ ์ค๋ฅ: {str(e)}") |
|
logger.error(traceback.format_exc()) |
|
raise |
|
|
|
|
|
if __name__ == "__main__": |
|
try: |
|
logger.info("์ ํ๋ฆฌ์ผ์ด์
์์") |
|
|
|
|
|
os.makedirs("imgs", exist_ok=True) |
|
logger.info("์ด๋ฏธ์ง ๋๋ ํ ๋ฆฌ ์ค๋น ์๋ฃ") |
|
|
|
|
|
if not os.environ.get("API_ENDPOINT"): |
|
logger.error("API_ENDPOINT ํ๊ฒฝ ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.") |
|
print("\nโ ์ค๋ฅ: API_ENDPOINT ํ๊ฒฝ ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.") |
|
print("ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๊ฑฐ๋ .env ํ์ผ์ API_ENDPOINT๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.") |
|
sys.exit(1) |
|
|
|
app = create_gradio_interface() |
|
logger.info("Gradio ์ฑ ์์") |
|
app.launch( |
|
share=True, |
|
server_name="0.0.0.0", |
|
server_port=7860, |
|
show_error=True, |
|
quiet=False |
|
) |
|
|
|
except KeyboardInterrupt: |
|
logger.info("์ฌ์ฉ์์ ์ํด ์ ํ๋ฆฌ์ผ์ด์
์ด ์ค๋จ๋์์ต๋๋ค.") |
|
except Exception as e: |
|
logger.error(f"์ฑ ์คํ ์ค๋ฅ: {str(e)}") |
|
logger.error(traceback.format_exc()) |
|
print(f"\nโ ์ฌ๊ฐํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}") |
|
print("์์ธํ ๋ด์ฉ์ app.log ํ์ผ์ ํ์ธํด์ฃผ์ธ์.") |