GitHub Actions
commited on
Commit
ยท
0996863
1
Parent(s):
9867d88
Auto-deploy from GitHub Actions - 2025-12-12 06:47:16
Browse files- app/gemini_client.py +84 -75
app/gemini_client.py
CHANGED
|
@@ -371,89 +371,98 @@ class GeminiClient:
|
|
| 371 |
|
| 372 |
print(f"[Gemini] v1 REST API ์๋ต ์ํ ์ฝ๋: {rest_response.status_code}")
|
| 373 |
|
| 374 |
-
# v1 ์๋ต๋ ํ์ธ
|
|
|
|
| 375 |
if rest_response.status_code == 200:
|
| 376 |
response_data_check_v1 = rest_response.json()
|
| 377 |
-
if 'error' in response_data_check_v1:
|
| 378 |
-
# v1
|
| 379 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
error_code_v1 = error_info_v1.get('code', 404)
|
| 381 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 382 |
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
|
| 412 |
-
|
| 413 |
-
fallback_model
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
url_fallback = f"{rest_base_url}/models/{fallback_model}:generateContent"
|
| 430 |
-
rest_response = requests.post(
|
| 431 |
-
url_fallback,
|
| 432 |
-
headers=headers,
|
| 433 |
-
json=request_body,
|
| 434 |
-
params=api_params,
|
| 435 |
-
timeout=timeout_seconds
|
| 436 |
-
)
|
| 437 |
-
# Fallback ์ฑ๊ณต ์ฌ๋ถ ํ์ธ
|
| 438 |
-
if rest_response.status_code == 200:
|
| 439 |
-
# ์ฑ๊ณต์ ์ผ๋ก ์๋ต ๋ฐ์ -> ๋ฃจํ ํ์ถ์ ์ํด response_has_error=False ์ ์ง
|
| 440 |
-
print(f"[Gemini] ๋์ฒด ๋ชจ๋ธ({fallback_model})๋ก ์ฌ์๋ ์ฑ๊ณต")
|
| 441 |
-
# ๋ชจ๋ธ๋ช
์ ๋์ฒด๋ ๊ฒ์ผ๋ก ์
๋ฐ์ดํธ (ํ ํฐ ์ ์ฅ ๋ฑ์ ์ํด)
|
| 442 |
-
model_name = fallback_model
|
| 443 |
-
else:
|
| 444 |
-
# Fallback๋ ์คํจํ๋ฉด ์๋ฌ ๋ฐ์
|
| 445 |
-
error_text_v1 = json.dumps(error_info_v1)
|
| 446 |
-
raise Exception(f"REST API ์ค๋ฅ {error_code_v1}: {error_text_v1}\n์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ: {available_models_str}\n๋์ฒด ์๋ ์คํจ: {fallback_model}")
|
| 447 |
else:
|
|
|
|
| 448 |
error_text_v1 = json.dumps(error_info_v1)
|
| 449 |
-
raise Exception(f"REST API ์ค๋ฅ {error_code_v1}: {error_text_v1}\n์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ: {available_models_str}")
|
| 450 |
else:
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
print(f"[Gemini] v1์์ ์ ์ ์๋ต ๋ฐ์")
|
| 454 |
-
elif rest_response.status_code != 200:
|
| 455 |
-
error_text_v1 = rest_response.text[:1000] if rest_response.text else '์์ธ ์ ๋ณด ์์'
|
| 456 |
-
raise Exception(f"REST API ์ค๋ฅ {rest_response.status_code}: {error_text_v1}")
|
| 457 |
elif error_code == 429:
|
| 458 |
# 429 ์ค๋ฅ: ํ ๋น๋ ์ด๊ณผ (์ฌ์๋ ๋ถ๊ฐ๋ฅ)
|
| 459 |
print(f"[Gemini] โ ํ ๋น๋ ์ด๊ณผ ์ค๋ฅ (429) ๊ฐ์ง")
|
|
|
|
| 371 |
|
| 372 |
print(f"[Gemini] v1 REST API ์๋ต ์ํ ์ฝ๋: {rest_response.status_code}")
|
| 373 |
|
| 374 |
+
# v1 ์๋ต๋ ํ์ธ (์ฑ๊ณต ๋๋ ์คํจ ๋ชจ๋ ์ฒ๋ฆฌ)
|
| 375 |
+
v1_success = False
|
| 376 |
if rest_response.status_code == 200:
|
| 377 |
response_data_check_v1 = rest_response.json()
|
| 378 |
+
if 'error' not in response_data_check_v1:
|
| 379 |
+
# v1์์ ์ฑ๊ณต
|
| 380 |
+
v1_success = True
|
| 381 |
+
response_has_error = False
|
| 382 |
+
print(f"[Gemini] v1์์ ์ ์ ์๋ต ๋ฐ์")
|
| 383 |
+
|
| 384 |
+
if not v1_success:
|
| 385 |
+
# v1์์๋ ์คํจ (์๋ฌ ๋๋ 404 ๋ฑ)
|
| 386 |
+
if rest_response.status_code == 200:
|
| 387 |
+
# 200 OK์ง๋ง ์๋ฌ ํ๋๊ฐ ์๋ ๊ฒฝ์ฐ
|
| 388 |
+
response_data_check_v1 = rest_response.json()
|
| 389 |
+
error_info_v1 = response_data_check_v1.get('error', {})
|
| 390 |
error_code_v1 = error_info_v1.get('code', 404)
|
| 391 |
+
else:
|
| 392 |
+
# HTTP ์๋ฌ (404 ๋ฑ)
|
| 393 |
+
error_code_v1 = rest_response.status_code
|
| 394 |
+
error_info_v1 = {'message': rest_response.text[:200]}
|
| 395 |
+
|
| 396 |
+
print(f"[Gemini] v1์์๋ ์คํจ (์ฝ๋: {error_code_v1}), ๋์ฒด ๋ชจ๋ธ ๊ฒ์ ์์...")
|
| 397 |
|
| 398 |
+
# ๋ชจ๋ธ ๋ชฉ๋ก ์กฐํ ์๋ (v1beta)
|
| 399 |
+
available_models_str = "ํ์ธ ๋ถ๊ฐ"
|
| 400 |
+
available_models_list = []
|
| 401 |
+
try:
|
| 402 |
+
list_models_url = f"{rest_base_url}/models"
|
| 403 |
+
list_response = requests.get(
|
| 404 |
+
list_models_url,
|
| 405 |
+
headers={"x-goog-api-key": api_key_clean},
|
| 406 |
+
params={"key": api_key_clean},
|
| 407 |
+
timeout=10
|
| 408 |
+
)
|
| 409 |
+
if list_response.status_code == 200:
|
| 410 |
+
models_data = list_response.json()
|
| 411 |
+
available_models_list = []
|
| 412 |
+
for m in models_data.get('models', []):
|
| 413 |
+
model_name_full = m.get('name', '')
|
| 414 |
+
if '/' in model_name_full:
|
| 415 |
+
model_name_short = model_name_full.split('/')[-1]
|
| 416 |
+
else:
|
| 417 |
+
model_name_short = model_name_full
|
| 418 |
+
# generateContent๋ฅผ ์ง์ํ๋ ๋ชจ๋ธ๋ง ํํฐ๋ง
|
| 419 |
+
supported_methods = m.get('supportedGenerationMethods', [])
|
| 420 |
+
if 'generateContent' in supported_methods:
|
| 421 |
+
available_models_list.append(model_name_short)
|
| 422 |
+
available_models_str = ', '.join(available_models_list[:10]) if available_models_list else '์์'
|
| 423 |
+
print(f"[Gemini] ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ ๋ชฉ๋ก (v1beta): {available_models_list[:10]}")
|
| 424 |
+
except Exception as list_error:
|
| 425 |
+
print(f"[Gemini] ๋ชจ๋ธ ๋ชฉ๋ก ์กฐํ ์คํจ: {list_error}")
|
| 426 |
+
|
| 427 |
+
# ๋์ฒด ๋ชจ๋ธ ์ฐพ๊ธฐ ๋ฐ ์ฌ์๋
|
| 428 |
+
fallback_model = None
|
| 429 |
+
# 1. ๋์ผ ๊ณ์ด ์ต์ ๋ชจ๋ธ ์ฐพ๊ธฐ
|
| 430 |
+
if 'gemini-1.5-pro' in model_name_clean:
|
| 431 |
+
for m in available_models_list:
|
| 432 |
+
if 'gemini-1.5-pro' in m and m != model_name_clean:
|
| 433 |
+
fallback_model = m
|
| 434 |
+
break
|
| 435 |
+
# 2. Flash ๋ชจ๋ธ๋ก ๋์ฒด
|
| 436 |
+
if not fallback_model and 'gemini-1.5-flash' in available_models_list:
|
| 437 |
+
fallback_model = 'gemini-1.5-flash'
|
| 438 |
+
# 3. ์๋ฌด ๋ชจ๋ธ์ด๋ ์ ํ
|
| 439 |
+
if not fallback_model and available_models_list:
|
| 440 |
+
fallback_model = available_models_list[0]
|
| 441 |
|
| 442 |
+
if fallback_model:
|
| 443 |
+
print(f"[Gemini] ๋ชจ๋ธ {model_name_clean}์(๋ฅผ) ์ฐพ์ ์ ์์ด {fallback_model}๋ก ๋์ฒดํ์ฌ ์ฌ์๋ํฉ๋๋ค.")
|
| 444 |
+
url_fallback = f"{rest_base_url}/models/{fallback_model}:generateContent"
|
| 445 |
+
rest_response = requests.post(
|
| 446 |
+
url_fallback,
|
| 447 |
+
headers=headers,
|
| 448 |
+
json=request_body,
|
| 449 |
+
params=api_params,
|
| 450 |
+
timeout=timeout_seconds
|
| 451 |
+
)
|
| 452 |
+
# Fallback ์ฑ๊ณต ์ฌ๋ถ ํ์ธ
|
| 453 |
+
if rest_response.status_code == 200:
|
| 454 |
+
# ์ฑ๊ณต์ ์ผ๋ก ์๋ต ๋ฐ์ -> ๋ฃจํ ํ์ถ์ ์ํด response_has_error=False ์ ์ง
|
| 455 |
+
print(f"[Gemini] ๋์ฒด ๋ชจ๋ธ({fallback_model})๋ก ์ฌ์๋ ์ฑ๊ณต")
|
| 456 |
+
# ๋ชจ๋ธ๋ช
์ ๋์ฒด๋ ๊ฒ์ผ๋ก ์
๋ฐ์ดํธ (ํ ํฐ ์ ์ฅ ๋ฑ์ ์ํด)
|
| 457 |
+
model_name = fallback_model
|
| 458 |
+
response_has_error = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
else:
|
| 460 |
+
# Fallback๋ ์คํจํ๋ฉด ์๋ฌ ๋ฐ์
|
| 461 |
error_text_v1 = json.dumps(error_info_v1)
|
| 462 |
+
raise Exception(f"REST API ์ค๋ฅ {error_code_v1}: {error_text_v1}\n์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ: {available_models_str}\n๋์ฒด ์๋ ์คํจ: {fallback_model}")
|
| 463 |
else:
|
| 464 |
+
error_text_v1 = json.dumps(error_info_v1)
|
| 465 |
+
raise Exception(f"REST API ์ค๋ฅ {error_code_v1}: {error_text_v1}\n์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ: {available_models_str}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
elif error_code == 429:
|
| 467 |
# 429 ์ค๋ฅ: ํ ๋น๋ ์ด๊ณผ (์ฌ์๋ ๋ถ๊ฐ๋ฅ)
|
| 468 |
print(f"[Gemini] โ ํ ๋น๋ ์ด๊ณผ ์ค๋ฅ (429) ๊ฐ์ง")
|