Leesn465 commited on
Commit
e3d71a6
·
verified ·
1 Parent(s): b9ea4b3

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +65 -31
main.py CHANGED
@@ -25,6 +25,7 @@ from datetime import datetime, timedelta
25
  from googletrans import Translator
26
  from starlette.concurrency import run_in_threadpool
27
  import FinanceDataReader as fdr
 
28
 
29
  app = FastAPI()
30
 
@@ -33,15 +34,16 @@ app = FastAPI()
33
  logging.basicConfig(level=logging.INFO)
34
  logger = logging.getLogger(__name__)
35
 
36
- API_KEY = os.getenv("GEMINI_API_KEY")
 
37
 
38
  if not API_KEY:
39
  # API 키가 없으면 에러를 발생시키거나 경고
40
- print("❌ GEMINI_API_KEY 환경 변수가 설정되지 않았습니다.")
41
 
42
  else:
43
- genai.configure(api_key=API_KEY)
44
- logger.info("✅ Gemini API 설정 완료 (환경 변수 사용)")
45
 
46
 
47
 
@@ -146,20 +148,44 @@ def parse_article_all(url: str) -> Dict[str, Any]:
146
  # 회사명 추론 (Gemini)
147
  # ---------------------------------------
148
 
149
- def gemini_use(text_for_company: str) -> str:
150
- generation_config = genai.GenerationConfig(temperature=1)
151
- model = genai.GenerativeModel('gemini-2.0-flash', generation_config=generation_config)
152
- prompt = f"""
153
- 아래 내용을 참고해서 가장 연관성이 높은 주식 상장 회사 이름 하나만 말해줘.
154
- 다른 설명 없이 회사 이름만 대답해.
 
 
 
 
 
155
 
156
- "{text_for_company}"
157
- """
158
- response = model.generate_content(prompt)
159
  try:
160
- return response.text.strip()
161
- except AttributeError:
162
- return response.candidates[0].content.parts[0].text.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  # ---------------------------------------
165
  # 1) 요약 단계
@@ -192,7 +218,7 @@ def step_company(inp: CompanyInput):
192
  text = ", ".join(inp.keywords)
193
  else:
194
  raise HTTPException(status_code=400, detail="summary 또는 keywords 중 하나가 필요합니다.")
195
- company = gemini_use(text)
196
  return {"company": company}
197
 
198
  # 4) 감정 단계
@@ -270,7 +296,7 @@ def parse_news(req: NewsRequest):
270
 
271
  # 키워드/요약(기존 resultKeyword 사용)
272
  rk = resultKeyword(meta["content"])
273
- targetCompany = gemini_use(rk) # 텍스트 변환은 f-string 내부에서 처리됨
274
 
275
  # 감정(기존 로직)
276
  s = analyze_sentiment(meta["content"])
@@ -360,22 +386,30 @@ async def load_initial_data():
360
  logger.error(f"🚨 초기 데이터 로딩 오류: {e}", exc_info=True)
361
 
362
  def get_stock_info(company_name: str) -> Dict[str, str] | None:
363
- kr_match = krx_listings[krx_listings['Name'].str.contains(company_name, case=False, na=False)]
364
- if not kr_match.empty:
365
- s = kr_match.iloc[0]
366
- return {"market": "KRX", "symbol": s['Code'], "name": s['Name']}
367
  try:
368
- company_name_eng = translator.translate(company_name, src='ko', dest='en').text
369
- us_match = us_listings[
370
- us_listings['Name'].str.contains(company_name_eng, case=False, na=False) |
371
- us_listings['Symbol'].str.fullmatch(company_name_eng, case=False)
372
- ]
373
- if not us_match.empty:
374
- s = us_match.iloc[0]
375
- return {"market": "US", "symbol": s['Symbol'], "name": s['Name']}
 
 
 
 
 
 
 
 
 
 
376
  except Exception as e:
377
- logger.error(f"번역/미국 주식 검색 오류: {e}")
 
378
  return None
 
379
 
380
  def fetch_stock_prices_sync(symbol: str, days: int = 365) -> Optional[pd.DataFrame]:
381
  end_date = datetime.today()
 
25
  from googletrans import Translator
26
  from starlette.concurrency import run_in_threadpool
27
  import FinanceDataReader as fdr
28
+ from groq import Groq
29
 
30
  app = FastAPI()
31
 
 
34
  logging.basicConfig(level=logging.INFO)
35
  logger = logging.getLogger(__name__)
36
 
37
+ API_KEY = os.getenv("GEMINI_API_KEY")
38
+
39
 
40
  if not API_KEY:
41
  # API 키가 없으면 에러를 발생시키거나 경고
42
+ print("❌ Groq_API_KEY 환경 변수가 설정되지 않았습니다.")
43
 
44
  else:
45
+ groq_client = Groq(api_key=API_KEY)
46
+ logger.info("✅ Groq API 설정 완료 (환경 변수 사용)")
47
 
48
 
49
 
 
148
  # 회사명 추론 (Gemini)
149
  # ---------------------------------------
150
 
151
+ # 3. 함수 이름 및 내용 변경 (gemini_use -> groq_use)
152
+ def groq_use(text_content: Any) -> str:
153
+ # 텍스트 추출 및 정제
154
+ if isinstance(text_content, dict):
155
+ text_for_ai = text_content.get('summary', '')
156
+ else:
157
+ text_for_ai = str(text_content)
158
+
159
+ # 프롬프트 구성 (불필요한 특수문자 제거 및 슬라이싱)
160
+ clean_text = text_for_ai[:500].replace('\n', ' ')
161
+ prompt = f"상장사 이름을 '회사명' 형식으로 하나만 답해줘: {clean_text}"
162
 
 
 
 
163
  try:
164
+ chat_completion = groq_client.chat.completions.create(
165
+ messages=[{
166
+ "role": "user",
167
+ "content": prompt
168
+ }],
169
+ model="llama-3.3-70b-versatile",
170
+ )
171
+ return chat_completion.choices[0].message.content.strip()
172
+
173
+ except Exception as e:
174
+ # 에러 객체를 직접 출력하지 말고 repr()을 사용해 ASCII 충돌 방지
175
+ logger.error(f"🚨 Groq 호출 실패: {repr(e)}")
176
+ return "추출 실패"
177
+
178
+ def get_stock_info(company_info: str) -> Dict[str, str] | None:
179
+ try:
180
+ if krx_listings is not None:
181
+ # 포함 관계 확인
182
+ for _, row in krx_listings.iterrows():
183
+ if row['Name'] in company_info:
184
+ return {"market": "KRX", "symbol": row['Code'], "name": row['Name']}
185
+ except Exception as e:
186
+ logger.error(f"주식 검색 에러: {e}")
187
+ return None
188
+
189
 
190
  # ---------------------------------------
191
  # 1) 요약 단계
 
218
  text = ", ".join(inp.keywords)
219
  else:
220
  raise HTTPException(status_code=400, detail="summary 또는 keywords 중 하나가 필요합니다.")
221
+ company = groq_use(text)
222
  return {"company": company}
223
 
224
  # 4) 감정 단계
 
296
 
297
  # 키워드/요약(기존 resultKeyword 사용)
298
  rk = resultKeyword(meta["content"])
299
+ targetCompany = groq_use(rk) # 텍스트 변환은 f-string 내부에서 처리됨
300
 
301
  # 감정(기존 로직)
302
  s = analyze_sentiment(meta["content"])
 
386
  logger.error(f"🚨 초기 데이터 로딩 오류: {e}", exc_info=True)
387
 
388
  def get_stock_info(company_name: str) -> Dict[str, str] | None:
 
 
 
 
389
  try:
390
+ # 1. 한국 주식(KRX) 검색
391
+ if krx_listings is not None:
392
+ kr_match = krx_listings[krx_listings['Name'].str.contains(company_name, case=False, na=False)]
393
+ if not kr_match.empty:
394
+ s = kr_match.iloc[0]
395
+ return {"market": "KRX", "symbol": s['Code'], "name": s['Name']}
396
+
397
+ # 2. 미국 주식 검색 (번역기 없이 이름으로 직접 검색)
398
+ if us_listings is not None:
399
+ # 영어 이름이 포함되어 있을 수 있으므로 대소문자 무시하고 검색
400
+ us_match = us_listings[
401
+ us_listings['Name'].str.contains(company_name, case=False, na=False) |
402
+ us_listings['Symbol'].str.fullmatch(company_name, case=False)
403
+ ]
404
+ if not us_match.empty:
405
+ s = us_match.iloc[0]
406
+ return {"market": "US", "symbol": s['Symbol'], "name": s['Name']}
407
+
408
  except Exception as e:
409
+ logger.error(f"주식 종목 검색 오류 발생: {e}")
410
+
411
  return None
412
+
413
 
414
  def fetch_stock_prices_sync(symbol: str, days: int = 365) -> Optional[pd.DataFrame]:
415
  end_date = datetime.today()