Spaces:
Running
Running
File size: 4,295 Bytes
0785301 7402e0f a6d62e8 2432a11 7402e0f a6d62e8 7402e0f a6d62e8 dec42d4 2432a11 dec42d4 2432a11 7402e0f dec42d4 2432a11 a6d62e8 7402e0f 0785301 dec42d4 7402e0f dec42d4 7402e0f dec42d4 a6d62e8 7402e0f a6d62e8 7402e0f 0785301 7402e0f 0785301 a6d62e8 0785301 2432a11 0785301 2432a11 7402e0f 2432a11 a6d62e8 2432a11 a6d62e8 2432a11 7402e0f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
import asyncio
import os
import logging
import random
import time
import re
from app.config import GEMINI_API_KEY, GEMINI_MODEL
try:
import google.genai as genai
try:
from google.genai import errors as genai_errors
except Exception:
genai_errors = None
except Exception:
genai = None
genai_errors = None
logging.warning("[summary_service] google.genai module not found; summary generation disabled")
try:
from google.api_core.exceptions import GoogleAPIError
except Exception:
GoogleAPIError = Exception
gemini_client = None
if not genai:
logging.warning("[summary_service] google.genai not available, summary generation will be disabled")
elif not GEMINI_API_KEY:
logging.warning("[summary_service] GEMINI_API_KEY is not set, summary generation will be disabled")
else:
try:
gemini_client = genai.Client(api_key=GEMINI_API_KEY)
logging.info(f"[summary_service] Initialized google.genai client with model={GEMINI_MODEL}")
except Exception as e:
logging.exception(f"[summary_service] Failed to init google.genai client: {e}")
gemini_client = None
async def generate_summary(text: str) -> str:
if not gemini_client:
return ""
if not text:
return ""
prompt = f"""
Bạn là chuyên gia tóm tắt. Hãy tóm tắt văn bản sau thành một đoạn văn duy nhất.
Yêu cầu:
1. Viết khoảng 3-5 câu, tổng hợp đầy đủ chủ đề và các ý chính.
2. Viết liền mạch, KHÔNG xuống dòng, KHÔNG dùng gạch đầu dòng hay đánh số.
3. Chỉ dựa trên thông tin được cung cấp, tuyệt đối KHÔNG tự thêm thông tin bên ngoài.
4. Trả về VĂN BẢN THUẦN (plain text), không bọc trong ``` hoặc JSON.
Văn bản:
\"\"\"{text}\"\"\"
"""
loop = asyncio.get_event_loop()
MAX_RETRIES = 3
BASE_DELAY = 1.0
def call():
last_exc = None
for attempt in range(1, MAX_RETRIES + 1):
try:
resp = gemini_client.models.generate_content(
model=GEMINI_MODEL,
contents=prompt,
)
return (resp.text or "").strip()
except Exception as e:
last_exc = e
is_server_error = False
try:
if genai_errors and isinstance(e, genai_errors.ServerError):
is_server_error = True
except Exception:
is_server_error = False
msg = str(e)
if "503" in msg or "UNAVAILABLE" in msg or is_server_error:
if attempt < MAX_RETRIES:
delay = BASE_DELAY * (2 ** (attempt - 1))
# add jitter
delay = delay + random.uniform(0, 0.5 * delay)
logging.warning(f"[summary_service] model overloaded (attempt {attempt}/{MAX_RETRIES}), retrying after {delay:.2f}s")
time.sleep(delay)
continue
# non-retryable or out of retries
logging.exception(f"[summary_service] generate_summary call failed on attempt {attempt}: {e}")
break
# propagate last exception to outer handler
if last_exc:
raise last_exc
return ""
try:
result = await loop.run_in_executor(None, call)
result = result.replace("```", "").strip()
if result:
return result
except GoogleAPIError as e:
logging.error(f"[summary_service] Gemini API error: {e}")
except Exception as e:
logging.exception(f"[summary_service] generate_summary failed: {e}")
# fallback: return a very small extracted summary (first 1-2 sentences) or empty
try:
sentences = re.split(r"(?<=[.!?])\s+", text.strip())
if not sentences:
return ""
fallback = " ".join(sentences[:2]).strip()
# keep fallback reasonably short
if len(fallback) > 400:
fallback = fallback[:400].rsplit(" ", 1)[0] + "..."
logging.info("[summary_service] Returning fallback summary after errors")
return fallback
except Exception:
return ""
|