프로젝트
ResourceExhausted
content0474
2025. 1. 21. 20:10
상황
챗봇코드와 cnn 크롤링 코드를 통합하여 크롤링 후 챗봇에 바로 기사를 넘기도록 함
오류 메시지
google.api_core.exceptions.ResourceExhausted: 429 Resource has been exhausted (e.g. check quota).
기존챗봇코드
class learnChat():
model = genai.GenerativeModel("gemini-1.5-flash")
chat = model.start_chat(history=[{'role':'user', 'parts':article.content}])
# fetch Gemini API Key
os.environ["GOOGLE_API_KEY"] = getpass("Gemini API Key:")
# create summary
def Summary():
summary=[]
summary[0] = chat.send_message("입력된 내용을 영어로 요약해서 출력해줘. 요약문은 100자 이내여야 해.").text
while len(summary)>400:
summary[0] = chat.send_message("너무 길어, 더 줄여줘.").text
summary[1] = chat.send_message("요약본을 한국어로 번역해줘").text
return summary
# create vocab
def vocab():
prompt="""
영문 요약본에서 적당한 난이도의 단어 3개만 찾아줘, 단어 옆에 한국어 뜻을 붙여줘. 단어와 뜻만 출력해.
예시:
collates 모으다
Crucial 중요한
Attributed 귀속된
"""
response = chat.send_message(prompt)
response=response.text.split('\n')
response.pop()
vocab={}
for i in range(len(response)):
v,m=response[i].split(maxsplit=1)
vocab[v]=m
return vocab
추정되는 원인
- CNN과 NYT 데이터를 처리하는 Celery 작업에서 챗봇 API를 호출할 때, 요청이 잦아 ResourceExhausted 오류발생
- 특히 요약과 번역 작업을 합쳐 실행하는 경우, 반복적인 요청으로 인해 Google Generative AI의 쿼터가 소진되는 것으로 추정
해결
- 요약과 번역을 별도의 함수로 분리
- 기존의 while len(summary[0]) > 400 루프를 제거하여 반복요청을 줄임
- time.sleep(5) 추가하여 요청간 간격 조정
수정한 챗봇코드
import google.generativeai as genai
import time
from django.conf import settings
genai.configure(api_key=settings.GEMINI_API_KEY)
class LearnChat:
def __init__(self, article_content):
self.model = genai.GenerativeModel("gemini-1.5-flash")
self.chat = self.model.start_chat(history=[{'role': 'user', 'parts': article_content}])
def summarize(self):
"""
기사 내용을 영어로 요약하는 함수.
"""
time.sleep(5) # 요청 간 대기 시간
return self.chat.send_message("입력된 내용을 핵심만 80자 이내로 영어로 요약해줘.").text
def translate_to_korean(self, english_text):
"""
영어 텍스트를 한국어로 번역하는 함수.
"""
time.sleep(5) # 요청 간 대기 시간
return self.chat.send_message(f"'{english_text}'를 한국어로 번역해줘.").text
def vocab(self, text):
"""
영어 텍스트에서 어려운 단어 3개를 추출하고, 한국어 뜻과 함께 반환하는 함수.
"""
prompt = f"""
'{text}'에서 적당한 난이도의 단어 3개를 찾아줘. 단어와 한국어 뜻만 출력해.
"""
response = self.chat.send_message(prompt)
vocab = {}
for line in response.text.split('\n'):
if line.strip():
word, meaning = line.split(maxsplit=1)
vocab[word] = meaning
return vocab
CNN 크롤링: 요약과 번역 모두
@shared_task
def fetch_and_store_cnn_news():
categories = Category.objects.all()
if not categories.exists():
print("No categories found in the database.")
return
for category in categories:
category_url = f"https://edition.cnn.com/{category.get_source_category(category.name, 'CNN')}"
articles = scrape_cnn_news_with_selenium(category_url)
if articles:
for article in articles:
chat = LearnChat(article['content'])
summary_english = chat.summarize()
summary_korean = chat.translate_to_korean(summary_english)
vocab = chat.vocab(summary_english)
redis_key = f"news:{category.name.lower()}:{article['url']}"
redis_value = json.dumps({
'title': article['title'],
'abstract': article['content'],
'summary_english': summary_english,
'summary_korean': summary_korean,
'vocab': vocab,
'url': article['url'],
'category': category.name
})
redis_client.set(redis_key, redis_value, ex=86400)
News.objects.update_or_create(
url=article['url'],
defaults={
'title': article['title'],
'abstract': article['content'],
'summary_english': summary_english,
'summary_korean': summary_korean,
'vocab': vocab,
'category': category
}
)
NYT: 요약본이 주어지므로 번역만 시행
@shared_task
def fetch_and_store_nyt_news():
categories = Category.objects.all()
if not categories.exists():
print("No categories found in the database.")
return
for category in categories:
category_url = f"https://api.nytimes.com/svc/topstories/v2/{category.get_source_category(category.name, 'NYTimes')}.json"
articles = get_nyt_articles(category_url) # NYT 기사 수집 함수
if articles:
for article in articles:
chat = LearnChat(article['abstract']) # NYT의 abstract를 사용
summary_korean = chat.translate_to_korean(article['abstract'])
vocab = chat.vocab(article['abstract'])
redis_key = f"news:{category.name.lower()}:{article['url']}"
redis_value = json.dumps({
'title': article['title'],
'abstract': article['abstract'],
'summary_english': article['abstract'], # NYT abstract 자체가 요약
'summary_korean': summary_korean,
'vocab': vocab,
'url': article['url'],
'category': category.name
})
redis_client.set(redis_key, redis_value, ex=86400)
News.objects.update_or_create(
url=article['url'],
defaults={
'title': article['title'],
'abstract': article['abstract'],
'summary_english': article['abstract'],
'summary_korean': summary_korean,
'vocab': vocab,
'category': category
}
)