Update app.py
Browse files
app.py
CHANGED
@@ -8,7 +8,7 @@ import traceback
|
|
8 |
import requests
|
9 |
from PIL import Image
|
10 |
import gradio as gr
|
11 |
-
from gradio_client import Client
|
12 |
from dotenv import load_dotenv
|
13 |
|
14 |
# 환경변수 로드
|
@@ -23,7 +23,7 @@ logging.basicConfig(
|
|
23 |
logging.StreamHandler(sys.stdout)
|
24 |
]
|
25 |
)
|
26 |
-
logger = logging.getLogger("image-enhancer-
|
27 |
|
28 |
# API 클라이언트 초기화 (환경변수에서)
|
29 |
API_ENDPOINT = os.environ.get("API_ENDPOINT")
|
@@ -33,7 +33,7 @@ if not API_ENDPOINT:
|
|
33 |
|
34 |
try:
|
35 |
# 로그에 엔드포인트 정보 출력하지 않음
|
36 |
-
|
37 |
logger.info("API client initialized successfully")
|
38 |
except Exception as e:
|
39 |
logger.error(f"Failed to initialize API client: {e}")
|
@@ -75,43 +75,114 @@ if not SIMPLE_BACKGROUNDS:
|
|
75 |
SIMPLE_BACKGROUNDS = {
|
76 |
"화이트 기본": "clean white background with soft lighting",
|
77 |
"회색 투톤": "light gray background with minimal shadows",
|
78 |
-
"라이트 그레이": "soft light gray backdrop with even illumination"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
if not STUDIO_BACKGROUNDS:
|
82 |
STUDIO_BACKGROUNDS = {
|
83 |
-
"연녹색 장미 정원": "soft green
|
84 |
-
"연분홍 장미 대리석": "pink rose with marble
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
}
|
86 |
|
87 |
if not NATURE_BACKGROUNDS:
|
88 |
NATURE_BACKGROUNDS = {
|
89 |
-
"작은 파도가 있는 해변": "
|
90 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
}
|
92 |
|
93 |
if not INDOOR_BACKGROUNDS:
|
94 |
INDOOR_BACKGROUNDS = {
|
95 |
-
"기본 책상": "
|
96 |
-
"빛이 비치는
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
|
99 |
if not SPECIAL_BACKGROUNDS:
|
100 |
SPECIAL_BACKGROUNDS = {
|
101 |
-
"네이비 빈티지 플로럴 벽지": "navy vintage floral wallpaper
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
|
104 |
if not JEWELRY_BACKGROUNDS:
|
105 |
JEWELRY_BACKGROUNDS = {
|
106 |
-
"화이트 미러 스팟 라이트": "white mirror
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
if not SPECIAL_EFFECTS_BACKGROUNDS:
|
110 |
SPECIAL_EFFECTS_BACKGROUNDS = {
|
111 |
-
"블루블랙 큰 물방울 효과": "blue
|
|
|
|
|
|
|
|
|
|
|
112 |
}
|
113 |
|
114 |
-
# 임시 파일 저장 함수
|
115 |
def save_uploaded_file(uploaded_file, suffix='.png'):
|
116 |
try:
|
117 |
logger.info(f"Processing uploaded file: {type(uploaded_file)}")
|
@@ -153,76 +224,7 @@ def save_uploaded_file(uploaded_file, suffix='.png'):
|
|
153 |
logger.error(traceback.format_exc())
|
154 |
return None
|
155 |
|
156 |
-
#
|
157 |
-
def api_update_dropdowns(bg_type):
|
158 |
-
"""드롭다운 업데이트 API 호출"""
|
159 |
-
try:
|
160 |
-
result = client.predict(bg_type=bg_type, api_name="/update_dropdowns")
|
161 |
-
return result
|
162 |
-
except Exception as e:
|
163 |
-
logger.error(f"Error calling update_dropdowns API: {e}")
|
164 |
-
return None
|
165 |
-
|
166 |
-
def api_generate_prompt_with_password_check(password, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, aspect_ratio):
|
167 |
-
"""프롬프트 생성 API 호출"""
|
168 |
-
try:
|
169 |
-
result = client.predict(
|
170 |
-
password=password,
|
171 |
-
bg_type=bg_type,
|
172 |
-
simple=simple,
|
173 |
-
studio=studio,
|
174 |
-
nature=nature,
|
175 |
-
indoor=indoor,
|
176 |
-
special=special,
|
177 |
-
jewelry=jewelry,
|
178 |
-
special_effects=special_effects,
|
179 |
-
request_text=request_text,
|
180 |
-
aspect_ratio=aspect_ratio,
|
181 |
-
api_name="/generate_prompt_with_password_check"
|
182 |
-
)
|
183 |
-
return result
|
184 |
-
except Exception as e:
|
185 |
-
logger.error(f"Error calling generate_prompt API: {e}")
|
186 |
-
return f"API 호출 오류: {str(e)}"
|
187 |
-
|
188 |
-
def api_check_password(password, image_file, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, quality_level, aspect_ratio, output_format, enable_enhancement):
|
189 |
-
"""이미지 처리 API 호출"""
|
190 |
-
try:
|
191 |
-
# 이미지 파일을 gradio_client의 handle_file로 처리
|
192 |
-
from gradio_client import handle_file
|
193 |
-
|
194 |
-
# 파일이 경로인 경우 handle_file로 래핑
|
195 |
-
if isinstance(image_file, str):
|
196 |
-
image_handle = handle_file(image_file)
|
197 |
-
else:
|
198 |
-
image_handle = image_file
|
199 |
-
|
200 |
-
result = client.predict(
|
201 |
-
password=password,
|
202 |
-
param_1=image_handle, # handle_file로 처리된 이미지
|
203 |
-
param_2=bg_type,
|
204 |
-
param_3=simple,
|
205 |
-
param_4=studio,
|
206 |
-
param_5=nature,
|
207 |
-
param_6=indoor,
|
208 |
-
param_7=special,
|
209 |
-
param_8=jewelry,
|
210 |
-
param_9=special_effects,
|
211 |
-
param_10=request_text,
|
212 |
-
param_11=quality_level,
|
213 |
-
param_12=aspect_ratio,
|
214 |
-
param_13=output_format,
|
215 |
-
param_14=enable_enhancement,
|
216 |
-
api_name="/check_password"
|
217 |
-
)
|
218 |
-
return result
|
219 |
-
except Exception as e:
|
220 |
-
logger.error(f"Error calling check_password API: {e}")
|
221 |
-
# 더 자세한 오류 정보 로깅
|
222 |
-
logger.error(f"Full error details: {traceback.format_exc()}")
|
223 |
-
return [], None, [], None, "", "", f"API 호출 오류: {str(e)}"
|
224 |
-
|
225 |
-
# Gradio 인터페이스 구성 (완전히 동일한 UI)
|
226 |
def create_gradio_interface():
|
227 |
try:
|
228 |
logger.info("Creating Gradio interface")
|
@@ -253,88 +255,84 @@ def create_gradio_interface():
|
|
253 |
|
254 |
# 드롭다운 컴포넌트들
|
255 |
simple_dropdown = gr.Dropdown(
|
256 |
-
choices=list(SIMPLE_BACKGROUNDS.keys())
|
257 |
-
value=list(SIMPLE_BACKGROUNDS.keys())[0] if SIMPLE_BACKGROUNDS else
|
258 |
label="심플 배경 선택",
|
259 |
visible=True,
|
260 |
interactive=True
|
261 |
)
|
262 |
|
263 |
studio_dropdown = gr.Dropdown(
|
264 |
-
choices=list(STUDIO_BACKGROUNDS.keys())
|
265 |
-
value=list(STUDIO_BACKGROUNDS.keys())[0] if STUDIO_BACKGROUNDS else
|
266 |
label="스튜디오 배경 선택",
|
267 |
visible=False,
|
268 |
interactive=True
|
269 |
)
|
270 |
|
271 |
nature_dropdown = gr.Dropdown(
|
272 |
-
choices=list(NATURE_BACKGROUNDS.keys())
|
273 |
-
value=list(NATURE_BACKGROUNDS.keys())[0] if NATURE_BACKGROUNDS else
|
274 |
label="자연 환경 선택",
|
275 |
visible=False,
|
276 |
interactive=True
|
277 |
)
|
278 |
|
279 |
indoor_dropdown = gr.Dropdown(
|
280 |
-
choices=list(INDOOR_BACKGROUNDS.keys())
|
281 |
-
value=list(INDOOR_BACKGROUNDS.keys())[0] if INDOOR_BACKGROUNDS else
|
282 |
label="실내 환경 선택",
|
283 |
visible=False,
|
284 |
interactive=True
|
285 |
)
|
286 |
|
287 |
special_dropdown = gr.Dropdown(
|
288 |
-
choices=list(SPECIAL_BACKGROUNDS.keys())
|
289 |
-
value=list(SPECIAL_BACKGROUNDS.keys())[0] if SPECIAL_BACKGROUNDS else
|
290 |
label="특수배경 선택",
|
291 |
visible=False,
|
292 |
interactive=True
|
293 |
)
|
294 |
|
295 |
jewelry_dropdown = gr.Dropdown(
|
296 |
-
choices=list(JEWELRY_BACKGROUNDS.keys())
|
297 |
-
value=list(JEWELRY_BACKGROUNDS.keys())[0] if JEWELRY_BACKGROUNDS else
|
298 |
label="주얼리 배경 선택",
|
299 |
visible=False,
|
300 |
interactive=True
|
301 |
)
|
302 |
|
303 |
special_effects_dropdown = gr.Dropdown(
|
304 |
-
choices=list(SPECIAL_EFFECTS_BACKGROUNDS.keys())
|
305 |
-
value=list(SPECIAL_EFFECTS_BACKGROUNDS.keys())[0] if SPECIAL_EFFECTS_BACKGROUNDS else
|
306 |
label="특수효과 배경 선택",
|
307 |
visible=False,
|
308 |
interactive=True
|
309 |
)
|
310 |
|
311 |
-
# 드롭다운 변경 함수 (원본과
|
312 |
def update_dropdowns(bg_type):
|
313 |
-
# API 호출하여 원본 동작 유지
|
314 |
try:
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
except:
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
special_effects_dropdown: gr.update(visible=(bg_type == "특수효과"))
|
330 |
-
}
|
331 |
|
332 |
-
# 원본과 동일한 엔드포인트 생성
|
333 |
background_type.change(
|
334 |
fn=update_dropdowns,
|
335 |
inputs=[background_type],
|
336 |
outputs=[simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, jewelry_dropdown, special_effects_dropdown],
|
337 |
-
api_name="update_dropdowns"
|
338 |
)
|
339 |
|
340 |
# 요청사항 입력
|
@@ -395,55 +393,73 @@ def create_gradio_interface():
|
|
395 |
info = gr.Textbox(label="처리 정보", interactive=False)
|
396 |
error = gr.Textbox(label="오류 메시지", interactive=False, visible=True)
|
397 |
|
398 |
-
# 프롬프트만 생성하는 함수 (원본과 동일한
|
399 |
def generate_prompt_with_password_check(password, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, aspect_ratio):
|
400 |
-
|
401 |
-
|
402 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
403 |
|
404 |
-
#
|
405 |
-
def check_password(password,
|
406 |
-
if image is None:
|
407 |
-
return [], None, [], None, "", "", "이미지를 업로드해야 합니다."
|
408 |
-
|
409 |
-
temp_path = None
|
410 |
try:
|
411 |
-
|
412 |
-
if isinstance(image, Image.Image):
|
413 |
-
temp_path = tempfile.mktemp(suffix='.png')
|
414 |
-
image.save(temp_path, format='PNG')
|
415 |
-
logger.info(f"Saved PIL image to temporary file: {temp_path}")
|
416 |
-
else:
|
417 |
-
temp_path = save_uploaded_file(image)
|
418 |
|
419 |
-
if
|
420 |
-
return [], None, [], None, "", "", "
|
421 |
-
|
422 |
-
# API 호출 전 파라미터 로깅 (민감한 정보 제외)
|
423 |
-
logger.info(f"Calling API with bg_type: {bg_type}, quality_level: {quality_level}")
|
424 |
|
425 |
-
#
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
)
|
430 |
-
return result
|
431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
except Exception as e:
|
433 |
-
logger.error(f"Error in check_password
|
434 |
-
|
435 |
-
return [], None, [], None, "", "", f"처리 중 오류 발생: {str(e)}"
|
436 |
-
|
437 |
-
finally:
|
438 |
-
# 임시 파일 정리
|
439 |
-
if temp_path and os.path.exists(temp_path):
|
440 |
-
try:
|
441 |
-
os.remove(temp_path)
|
442 |
-
logger.info(f"Cleaned up temporary file: {temp_path}")
|
443 |
-
except Exception as cleanup_error:
|
444 |
-
logger.warning(f"Failed to cleanup temp file {temp_path}: {cleanup_error}")
|
445 |
|
446 |
-
# 프롬프트 생성 버튼 클릭 이벤트
|
447 |
generate_prompt_btn.click(
|
448 |
fn=generate_prompt_with_password_check,
|
449 |
inputs=[
|
@@ -454,10 +470,10 @@ def create_gradio_interface():
|
|
454 |
request_text, aspect_ratio
|
455 |
],
|
456 |
outputs=[prompt_output],
|
457 |
-
api_name="generate_prompt_with_password_check"
|
458 |
)
|
459 |
|
460 |
-
# 편집 버튼 클릭 이벤트
|
461 |
edit_btn.click(
|
462 |
fn=check_password,
|
463 |
inputs=[
|
@@ -472,7 +488,7 @@ def create_gradio_interface():
|
|
472 |
enhanced_output, enhanced_download,
|
473 |
prompt_output, info, error
|
474 |
],
|
475 |
-
api_name="check_password"
|
476 |
)
|
477 |
|
478 |
logger.info("Gradio interface created successfully")
|
@@ -485,7 +501,7 @@ def create_gradio_interface():
|
|
485 |
# 앱 실행
|
486 |
if __name__ == "__main__":
|
487 |
try:
|
488 |
-
logger.info("Starting
|
489 |
|
490 |
# imgs 디렉토리 확인/생성
|
491 |
os.makedirs("imgs", exist_ok=True)
|
|
|
8 |
import requests
|
9 |
from PIL import Image
|
10 |
import gradio as gr
|
11 |
+
from gradio_client import Client, handle_file
|
12 |
from dotenv import load_dotenv
|
13 |
|
14 |
# 환경변수 로드
|
|
|
23 |
logging.StreamHandler(sys.stdout)
|
24 |
]
|
25 |
)
|
26 |
+
logger = logging.getLogger("image-enhancer-app")
|
27 |
|
28 |
# API 클라이언트 초기화 (환경변수에서)
|
29 |
API_ENDPOINT = os.environ.get("API_ENDPOINT")
|
|
|
33 |
|
34 |
try:
|
35 |
# 로그에 엔드포인트 정보 출력하지 않음
|
36 |
+
api_client = Client(API_ENDPOINT)
|
37 |
logger.info("API client initialized successfully")
|
38 |
except Exception as e:
|
39 |
logger.error(f"Failed to initialize API client: {e}")
|
|
|
75 |
SIMPLE_BACKGROUNDS = {
|
76 |
"화이트 기본": "clean white background with soft lighting",
|
77 |
"회색 투톤": "light gray background with minimal shadows",
|
78 |
+
"라이트 그레이": "soft light gray backdrop with even illumination",
|
79 |
+
"그레이 그라데이션 스포트라이트": "gray gradient with spotlight",
|
80 |
+
"프리미엄 드라마틱 블랙": "premium dramatic black background",
|
81 |
+
"딥블루 유리반사": "deep blue glass reflection",
|
82 |
+
"파스텔 그라데이션": "pastel gradient background",
|
83 |
+
"스카이블루 파스텔": "sky blue pastel",
|
84 |
+
"버터옐로우 파스텔": "butter yellow pastel",
|
85 |
+
"블루 원색": "pure blue background",
|
86 |
+
"레드 원색": "pure red background"
|
87 |
}
|
88 |
|
89 |
if not STUDIO_BACKGROUNDS:
|
90 |
STUDIO_BACKGROUNDS = {
|
91 |
+
"연녹색 장미 정원": "soft green rose garden",
|
92 |
+
"연분홍 장미 대리석": "pink rose with marble",
|
93 |
+
"파스텔 블루 수국": "pastel blue hydrangea",
|
94 |
+
"소프트 핑크 벚꽃": "soft pink cherry blossom",
|
95 |
+
"파스텔 옐로우 꽃봉오리": "pastel yellow buds",
|
96 |
+
"아이보리 로즈 심플": "ivory rose simple",
|
97 |
+
"심플 화이트 작은 화분": "simple white small pot",
|
98 |
+
"퍼플 장난스러운 심비로운 분위기": "purple playful mood",
|
99 |
+
"코지 데스크 플랜트": "cozy desk plant",
|
100 |
+
"연핑크 튤립 작은테이블": "light pink tulip small table",
|
101 |
+
"오크우드 튤립 샤워 푸프": "oak wood tulip shower puff",
|
102 |
+
"크림 코튼": "cream cotton",
|
103 |
+
"브라운 거친 페이퍼": "brown rough paper"
|
104 |
}
|
105 |
|
106 |
if not NATURE_BACKGROUNDS:
|
107 |
NATURE_BACKGROUNDS = {
|
108 |
+
"작은 파도가 있는 해변": "beach with small waves",
|
109 |
+
"펭귄이 있는 빙산": "iceberg with penguin",
|
110 |
+
"눈내리는 산악 설원": "snowy mountain field",
|
111 |
+
"열대해변": "tropical beach",
|
112 |
+
"일출 직전의 바위산": "rocky mountain before sunrise",
|
113 |
+
"초근접 봄꽃 들판": "close-up spring flower field",
|
114 |
+
"물가 바위": "waterside rocks",
|
115 |
+
"작은 돌이 깔린 얕은 물가": "shallow water with small stones",
|
116 |
+
"나무 테이블 숲속 계곡": "wooden table forest valley",
|
117 |
+
"안개 낀 숲": "foggy forest",
|
118 |
+
"일몰 바다": "sunset sea",
|
119 |
+
"별이 빛나는 캠핑": "starry camping"
|
120 |
}
|
121 |
|
122 |
if not INDOOR_BACKGROUNDS:
|
123 |
INDOOR_BACKGROUNDS = {
|
124 |
+
"기본 책상": "basic desk",
|
125 |
+
"빛이 비치는 책상": "desk with light",
|
126 |
+
"빛이 비치는 거실": "living room with light",
|
127 |
+
"스튜디어 거실": "studio living room",
|
128 |
+
"화분이 있는 거실": "living room with plants",
|
129 |
+
"전체적인 거실모습": "overall living room view",
|
130 |
+
"포인트 거실": "point living room",
|
131 |
+
"중앙 거실": "central living room",
|
132 |
+
"서랍테이블": "drawer table",
|
133 |
+
"침실 탁자위": "bedroom table top",
|
134 |
+
"원목 테이블 블록": "wood table block",
|
135 |
+
"테이블 심플": "simple table",
|
136 |
+
"분위기 있는 침실": "atmospheric bedroom",
|
137 |
+
"나무테이블위": "on wooden table",
|
138 |
+
"책위 거실테이블": "living room table with books",
|
139 |
+
"유리테이블위": "on glass table",
|
140 |
+
"침실 옆 작은탁자": "small bedside table",
|
141 |
+
"분위기 있는 원형 테이블": "atmospheric round table",
|
142 |
+
"포커스 탁자": "focus table",
|
143 |
+
"투톤 벽면": "two-tone wall",
|
144 |
+
"아늑한 테이블위 액세서리": "cozy table accessories",
|
145 |
+
"아늑�� 테이블 보 위": "on cozy tablecloth",
|
146 |
+
"유리 바닥": "glass floor",
|
147 |
+
"빛치는 식탁위": "dining table with light",
|
148 |
+
"나늑한 식탁위 작업대": "cozy dining workspace"
|
149 |
}
|
150 |
|
151 |
if not SPECIAL_BACKGROUNDS:
|
152 |
SPECIAL_BACKGROUNDS = {
|
153 |
+
"네이비 빈티지 플로럴 벽지": "navy vintage floral wallpaper",
|
154 |
+
"빈티지 꽃무늬 패브릭 배경": "vintage floral fabric background",
|
155 |
+
"팝 도트와 과일": "pop dots and fruits",
|
156 |
+
"블루 마블 잉크 텍스처 배경": "blue marble ink texture",
|
157 |
+
"오렌지블루 워터컬러 배경": "orange blue watercolor",
|
158 |
+
"레드브러시 페인팅 아트 배경": "red brush painting art",
|
159 |
+
"블루오렌지 페인팅 아트": "blue orange painting art"
|
160 |
}
|
161 |
|
162 |
if not JEWELRY_BACKGROUNDS:
|
163 |
JEWELRY_BACKGROUNDS = {
|
164 |
+
"화이트 미러 스팟 라이트": "white mirror spotlight",
|
165 |
+
"그레이 그라데이션 미러": "gray gradient mirror",
|
166 |
+
"네이비 벨벳": "navy velvet",
|
167 |
+
"블랙 미러 시네마틱": "black mirror cinematic",
|
168 |
+
"화이트 마블 프리미엄": "white marble premium",
|
169 |
+
"파스텔 블루 큐브 플랫폼": "pastel blue cube platform",
|
170 |
+
"내추럴 그라스": "natural grass",
|
171 |
+
"소프트 베이직 패브릭": "soft basic fabric",
|
172 |
+
"마이크로텍스쳐 프리미엄": "micro texture premium"
|
173 |
}
|
174 |
|
175 |
if not SPECIAL_EFFECTS_BACKGROUNDS:
|
176 |
SPECIAL_EFFECTS_BACKGROUNDS = {
|
177 |
+
"블루블랙 큰 물방울 효과": "blue black water drop effect",
|
178 |
+
"크리스탈 버블 물속 장면": "crystal bubble underwater scene",
|
179 |
+
"잔 물결 수면 위 장면": "gentle ripple water surface scene",
|
180 |
+
"컬러 스모크 효과": "color smoke effect",
|
181 |
+
"자옥한 안개 효과": "dense fog effect",
|
182 |
+
"가습기 수중기 효과": "humidifier mist effect"
|
183 |
}
|
184 |
|
185 |
+
# 임시 파일 저장 함수 (원본과 동일)
|
186 |
def save_uploaded_file(uploaded_file, suffix='.png'):
|
187 |
try:
|
188 |
logger.info(f"Processing uploaded file: {type(uploaded_file)}")
|
|
|
224 |
logger.error(traceback.format_exc())
|
225 |
return None
|
226 |
|
227 |
+
# Gradio 인터페이스 구성 (원본과 완전 동일)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
def create_gradio_interface():
|
229 |
try:
|
230 |
logger.info("Creating Gradio interface")
|
|
|
255 |
|
256 |
# 드롭다운 컴포넌트들
|
257 |
simple_dropdown = gr.Dropdown(
|
258 |
+
choices=list(SIMPLE_BACKGROUNDS.keys()),
|
259 |
+
value=list(SIMPLE_BACKGROUNDS.keys())[0] if SIMPLE_BACKGROUNDS else None,
|
260 |
label="심플 배경 선택",
|
261 |
visible=True,
|
262 |
interactive=True
|
263 |
)
|
264 |
|
265 |
studio_dropdown = gr.Dropdown(
|
266 |
+
choices=list(STUDIO_BACKGROUNDS.keys()),
|
267 |
+
value=list(STUDIO_BACKGROUNDS.keys())[0] if STUDIO_BACKGROUNDS else None,
|
268 |
label="스튜디오 배경 선택",
|
269 |
visible=False,
|
270 |
interactive=True
|
271 |
)
|
272 |
|
273 |
nature_dropdown = gr.Dropdown(
|
274 |
+
choices=list(NATURE_BACKGROUNDS.keys()),
|
275 |
+
value=list(NATURE_BACKGROUNDS.keys())[0] if NATURE_BACKGROUNDS else None,
|
276 |
label="자연 환경 선택",
|
277 |
visible=False,
|
278 |
interactive=True
|
279 |
)
|
280 |
|
281 |
indoor_dropdown = gr.Dropdown(
|
282 |
+
choices=list(INDOOR_BACKGROUNDS.keys()),
|
283 |
+
value=list(INDOOR_BACKGROUNDS.keys())[0] if INDOOR_BACKGROUNDS else None,
|
284 |
label="실내 환경 선택",
|
285 |
visible=False,
|
286 |
interactive=True
|
287 |
)
|
288 |
|
289 |
special_dropdown = gr.Dropdown(
|
290 |
+
choices=list(SPECIAL_BACKGROUNDS.keys()),
|
291 |
+
value=list(SPECIAL_BACKGROUNDS.keys())[0] if SPECIAL_BACKGROUNDS else None,
|
292 |
label="특수배경 선택",
|
293 |
visible=False,
|
294 |
interactive=True
|
295 |
)
|
296 |
|
297 |
jewelry_dropdown = gr.Dropdown(
|
298 |
+
choices=list(JEWELRY_BACKGROUNDS.keys()),
|
299 |
+
value=list(JEWELRY_BACKGROUNDS.keys())[0] if JEWELRY_BACKGROUNDS else None,
|
300 |
label="주얼리 배경 선택",
|
301 |
visible=False,
|
302 |
interactive=True
|
303 |
)
|
304 |
|
305 |
special_effects_dropdown = gr.Dropdown(
|
306 |
+
choices=list(SPECIAL_EFFECTS_BACKGROUNDS.keys()),
|
307 |
+
value=list(SPECIAL_EFFECTS_BACKGROUNDS.keys())[0] if SPECIAL_EFFECTS_BACKGROUNDS else None,
|
308 |
label="특수효과 배경 선택",
|
309 |
visible=False,
|
310 |
interactive=True
|
311 |
)
|
312 |
|
313 |
+
# 드롭다운 변경 함수 (원본과 동일, API 엔드포인트 생성)
|
314 |
def update_dropdowns(bg_type):
|
|
|
315 |
try:
|
316 |
+
# API 호출
|
317 |
+
result = api_client.predict(bg_type=bg_type, api_name="/update_dropdowns")
|
318 |
+
return result
|
319 |
except:
|
320 |
+
# 백업용 로컬 로직
|
321 |
+
return {
|
322 |
+
simple_dropdown: gr.update(visible=(bg_type == "심플 배경")),
|
323 |
+
studio_dropdown: gr.update(visible=(bg_type == "스튜디오 배경")),
|
324 |
+
nature_dropdown: gr.update(visible=(bg_type == "자연 환경")),
|
325 |
+
indoor_dropdown: gr.update(visible=(bg_type == "실내 환경")),
|
326 |
+
special_dropdown: gr.update(visible=(bg_type == "특수배경")),
|
327 |
+
jewelry_dropdown: gr.update(visible=(bg_type == "주얼리")),
|
328 |
+
special_effects_dropdown: gr.update(visible=(bg_type == "특수효과"))
|
329 |
+
}
|
|
|
|
|
330 |
|
|
|
331 |
background_type.change(
|
332 |
fn=update_dropdowns,
|
333 |
inputs=[background_type],
|
334 |
outputs=[simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, jewelry_dropdown, special_effects_dropdown],
|
335 |
+
api_name="update_dropdowns"
|
336 |
)
|
337 |
|
338 |
# 요청사항 입력
|
|
|
393 |
info = gr.Textbox(label="처리 정보", interactive=False)
|
394 |
error = gr.Textbox(label="오류 메시지", interactive=False, visible=True)
|
395 |
|
396 |
+
# 프롬프트만 생성하는 함수 (원본과 동일한 엔드포인트, API 호출)
|
397 |
def generate_prompt_with_password_check(password, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, aspect_ratio):
|
398 |
+
try:
|
399 |
+
return api_client.predict(
|
400 |
+
password=password,
|
401 |
+
bg_type=bg_type,
|
402 |
+
simple=simple,
|
403 |
+
studio=studio,
|
404 |
+
nature=nature,
|
405 |
+
indoor=indoor,
|
406 |
+
special=special,
|
407 |
+
jewelry=jewelry,
|
408 |
+
special_effects=special_effects,
|
409 |
+
request_text=request_text,
|
410 |
+
aspect_ratio=aspect_ratio,
|
411 |
+
api_name="/generate_prompt_with_password_check"
|
412 |
+
)
|
413 |
+
except Exception as e:
|
414 |
+
return f"API 호출 오류: {str(e)}"
|
415 |
|
416 |
+
# 비밀번호 확인 함수 (원본과 동일한 엔드포인트, API 호출)
|
417 |
+
def check_password(password, *args):
|
|
|
|
|
|
|
|
|
418 |
try:
|
419 |
+
image, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, quality_level, aspect_ratio, output_format, enable_enhancement = args
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
|
421 |
+
if image is None:
|
422 |
+
return ([], None, [], None, "", "", "이미지를 업로드해야 합니다.")
|
|
|
|
|
|
|
423 |
|
424 |
+
# 이미지를 임시 파일로 저장
|
425 |
+
temp_path = save_uploaded_file(image)
|
426 |
+
if temp_path is None:
|
427 |
+
return ([], None, [], None, "", "", "이미지 처리에 실패했습니다.")
|
|
|
|
|
428 |
|
429 |
+
try:
|
430 |
+
# API 호출 (원본과 동일한 파라미터)
|
431 |
+
result = api_client.predict(
|
432 |
+
password=password,
|
433 |
+
param_1=handle_file(temp_path),
|
434 |
+
param_2=bg_type,
|
435 |
+
param_3=simple,
|
436 |
+
param_4=studio,
|
437 |
+
param_5=nature,
|
438 |
+
param_6=indoor,
|
439 |
+
param_7=special,
|
440 |
+
param_8=jewelry,
|
441 |
+
param_9=special_effects,
|
442 |
+
param_10=request_text,
|
443 |
+
param_11=quality_level,
|
444 |
+
param_12=aspect_ratio,
|
445 |
+
param_13=output_format,
|
446 |
+
param_14=enable_enhancement,
|
447 |
+
api_name="/check_password"
|
448 |
+
)
|
449 |
+
return result
|
450 |
+
finally:
|
451 |
+
# 임시 파일 정리
|
452 |
+
if os.path.exists(temp_path):
|
453 |
+
try:
|
454 |
+
os.remove(temp_path)
|
455 |
+
except:
|
456 |
+
pass
|
457 |
+
|
458 |
except Exception as e:
|
459 |
+
logger.error(f"Error in check_password: {e}")
|
460 |
+
return ([], None, [], None, "", "", f"오류 발생: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
|
462 |
+
# 프롬프트 생성 버튼 클릭 이벤트
|
463 |
generate_prompt_btn.click(
|
464 |
fn=generate_prompt_with_password_check,
|
465 |
inputs=[
|
|
|
470 |
request_text, aspect_ratio
|
471 |
],
|
472 |
outputs=[prompt_output],
|
473 |
+
api_name="generate_prompt_with_password_check"
|
474 |
)
|
475 |
|
476 |
+
# 편집 버튼 클릭 이벤트
|
477 |
edit_btn.click(
|
478 |
fn=check_password,
|
479 |
inputs=[
|
|
|
488 |
enhanced_output, enhanced_download,
|
489 |
prompt_output, info, error
|
490 |
],
|
491 |
+
api_name="check_password"
|
492 |
)
|
493 |
|
494 |
logger.info("Gradio interface created successfully")
|
|
|
501 |
# 앱 실행
|
502 |
if __name__ == "__main__":
|
503 |
try:
|
504 |
+
logger.info("Starting application")
|
505 |
|
506 |
# imgs 디렉토리 확인/생성
|
507 |
os.makedirs("imgs", exist_ok=True)
|