JUNGU commited on
Commit
e71bfbd
ยท
verified ยท
1 Parent(s): a204a9d

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +22 -30
src/streamlit_app.py CHANGED
@@ -11,7 +11,7 @@ from collections import Counter
11
  import json
12
  import os
13
  from datetime import datetime, timedelta
14
- from openai import OpenAI
15
  from dotenv import load_dotenv
16
  import traceback
17
  import plotly.graph_objects as go
@@ -42,7 +42,6 @@ global_scheduler_state = SchedulerState()
42
  # API ํ‚ค ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์„ธ์…˜ ์ƒํƒœ ์ดˆ๊ธฐํ™”
43
  if 'openai_api_key' not in st.session_state:
44
  st.session_state.openai_api_key = None
45
- st.session_state.openai_client = None
46
 
47
  # ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์œผ๋กœ API ํ‚ค ๋กœ๋“œ ์‹œ๋„
48
  load_dotenv() # .env ํŒŒ์ผ์—์„œ ๋กœ๋“œ ์‹œ๋„
@@ -50,19 +49,17 @@ load_dotenv() # .env ํŒŒ์ผ์—์„œ ๋กœ๋“œ ์‹œ๋„
50
  # 1. ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ API ํ‚ค ํ™•์ธ
51
  if os.environ.get('OPENAI_API_KEY'):
52
  st.session_state.openai_api_key = os.environ.get('OPENAI_API_KEY')
 
53
 
54
  # 2. Streamlit secrets์—์„œ API ํ‚ค ํ™•์ธ (try-except๋กœ ์˜ค๋ฅ˜ ๋ฐฉ์ง€)
55
  if not st.session_state.openai_api_key:
56
  try:
57
  if 'OPENAI_API_KEY' in st.secrets:
58
  st.session_state.openai_api_key = st.secrets['OPENAI_API_KEY']
 
59
  except Exception as e:
60
  pass # secrets ํŒŒ์ผ์ด ์—†์–ด๋„ ์˜ค๋ฅ˜ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
61
 
62
- # 3. API ํ‚ค๊ฐ€ ์žˆ์œผ๋ฉด ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
63
- if st.session_state.openai_api_key:
64
- st.session_state.openai_client = OpenAI(api_key=st.session_state.openai_api_key)
65
-
66
  # ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก NLTK ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์„ค์ •
67
  nltk_data_dir = '/tmp/nltk_data'
68
  os.makedirs(nltk_data_dir, exist_ok=True)
@@ -94,7 +91,7 @@ with st.sidebar:
94
  api_key = st.text_input("OpenAI API ํ‚ค ์ž…๋ ฅ", type="password")
95
  if api_key:
96
  st.session_state.openai_api_key = api_key
97
- st.session_state.openai_client = OpenAI(api_key=api_key)
98
  st.success("API ํ‚ค๊ฐ€ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค!")
99
 
100
  # ์ €์žฅ๋œ ๊ธฐ์‚ฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ•จ์ˆ˜
@@ -328,13 +325,13 @@ def analyze_news_content(news_df):
328
  results['top_keywords'] = []
329
  return results
330
 
331
- # OpenAI API๋ฅผ ์ด์šฉํ•œ ์ƒˆ ๊ธฐ์‚ฌ ์ƒ์„ฑ
332
  def generate_article(original_content, prompt_text):
333
  try:
334
- if not st.session_state.openai_client:
335
  return "OpenAI API ํ‚ค๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
336
 
337
- response = st.session_state.openai_client.chat.completions.create(
338
  model="gpt-4.1-mini",
339
  messages=[
340
  {"role": "system", "content": "๋‹น์‹ ์€ ์ „๋ฌธ์ ์ธ ๋‰ด์Šค ๊ธฐ์ž์ž…๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”."},
@@ -342,26 +339,22 @@ def generate_article(original_content, prompt_text):
342
  ],
343
  max_tokens=2000
344
  )
345
- return response.choices[0].message.content
346
  except Exception as e:
347
  return f"๊ธฐ์‚ฌ ์ƒ์„ฑ ์˜ค๋ฅ˜: {str(e)}"
348
 
349
- # OpenAI API๋ฅผ ์ด์šฉํ•œ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
350
  def generate_image(prompt):
351
  try:
352
- if not st.session_state.openai_client:
353
  return "OpenAI API ํ‚ค๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
354
 
355
- response = st.session_state.openai_client.images.generate(
356
- model="gpt-image-1",
357
- prompt=prompt
 
358
  )
359
- try:
360
- image_base64 = response.data[0].b64_json
361
- return f"data:image/png;base64,{image_base64}"
362
- except AttributeError:
363
- # b64_json๊ฐ€ ์—†์„ ๊ฒฝ์šฐ URL ์‚ฌ์šฉ
364
- return response.data[0].url
365
  except Exception as e:
366
  return f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์˜ค๋ฅ˜: {str(e)}"
367
 
@@ -714,22 +707,21 @@ elif menu == "๊ธฐ์‚ฌ ๋ถ„์„ํ•˜๊ธฐ":
714
 
715
  elif analysis_type == "๊ฐ์ • ๋ถ„์„":
716
  if st.button("๊ฐ์ • ๋ถ„์„ํ•˜๊ธฐ"):
717
- if st.session_state.openai_client:
718
  with st.spinner("๊ธฐ์‚ฌ์˜ ๊ฐ์ •์„ ๋ถ„์„ ์ค‘์ž…๋‹ˆ๋‹ค..."):
719
  try:
720
- # ๊ฐ์ • ๋ถ„์„ ํ”„๋กฌํ”„ํŠธ ์„ค์ •
721
- response = st.session_state.openai_client.chat.completions.create(
722
  model="gpt-4.1-mini",
723
  messages=[
724
  {"role": "system", "content": "๋‹น์‹ ์€ ํ…์ŠคํŠธ์˜ ๊ฐ์ •๊ณผ ๋…ผ์กฐ๋ฅผ ๋ถ„์„ํ•˜๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‰ด์Šค ๊ธฐ์‚ฌ๏ฟฝ๏ฟฝ๏ฟฝ ๊ฐ์ •๊ณผ ๋…ผ์กฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ , '๊ธ์ •์ ', '๋ถ€์ •์ ', '์ค‘๋ฆฝ์ ' ์ค‘ ํ•˜๋‚˜๋กœ ๋ถ„๋ฅ˜ํ•ด ์ฃผ์„ธ์š”. ๋˜ํ•œ ๊ธฐ์‚ฌ์—์„œ ๋“œ๋Ÿฌ๋‚˜๋Š” ํ•ต์‹ฌ ๊ฐ์ • ํ‚ค์›Œ๋“œ๋ฅผ 5๊ฐœ ์ถ”์ถœํ•˜๊ณ , ๊ฐ ํ‚ค์›Œ๋“œ๋ณ„๋กœ 1-10 ์‚ฌ์ด์˜ ๊ฐ•๋„ ์ ์ˆ˜๋ฅผ ๋งค๊ฒจ์ฃผ์„ธ์š”. JSON ํ˜•์‹์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‘๋‹ตํ•ด์ฃผ์„ธ์š”: {'sentiment': '๊ธ์ •์ /๋ถ€์ •์ /์ค‘๋ฆฝ์ ', 'reason': '์ด์œ  ์„ค๋ช…...', 'keywords': [{'word': 'ํ‚ค์›Œ๋“œ1', 'score': 8}, {'word': 'ํ‚ค์›Œ๋“œ2', 'score': 7}, ...]}"},
725
  {"role": "user", "content": f"๋‹ค์Œ ๋‰ด์Šค ๊ธฐ์‚ฌ๋ฅผ ๋ถ„์„ํ•ด ์ฃผ์„ธ์š”:\n\n์ œ๋ชฉ: {selected_article['title']}\n\n๋‚ด์šฉ: {selected_article['content'][:1500]}"}
726
  ],
727
- max_tokens=800,
728
- response_format={"type": "json_object"}
729
  )
730
 
731
- # JSON ํŒŒ์‹ฑ
732
- analysis_result = json.loads(response.choices[0].message.content)
733
 
734
  # ๊ฒฐ๊ณผ ์‹œ๊ฐํ™”
735
  st.subheader("๊ฐ์ • ๋ถ„์„ ๊ฒฐ๊ณผ")
@@ -915,7 +907,7 @@ elif menu == "์ƒˆ ๊ธฐ์‚ฌ ์ƒ์„ฑํ•˜๊ธฐ":
915
  generate_image_too = st.checkbox("๊ธฐ์‚ฌ ์ƒ์„ฑ ํ›„ ์ด๋ฏธ์ง€๋„ ํ•จ๊ป˜ ์ƒ์„ฑํ•˜๊ธฐ", value=True)
916
 
917
  if st.button("์ƒˆ ๊ธฐ์‚ฌ ์ƒ์„ฑํ•˜๊ธฐ"):
918
- if st.session_state.openai_client:
919
  with st.spinner("๊ธฐ์‚ฌ๋ฅผ ์ƒ์„ฑ ์ค‘์ž…๋‹ˆ๋‹ค..."):
920
  new_article = generate_article(selected_article['content'], prompt_text)
921
 
 
11
  import json
12
  import os
13
  from datetime import datetime, timedelta
14
+ import openai # ๊ตฌ ๋ฒ„์ „ ๋ฐฉ์‹ ์‚ฌ์šฉ
15
  from dotenv import load_dotenv
16
  import traceback
17
  import plotly.graph_objects as go
 
42
  # API ํ‚ค ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์„ธ์…˜ ์ƒํƒœ ์ดˆ๊ธฐํ™”
43
  if 'openai_api_key' not in st.session_state:
44
  st.session_state.openai_api_key = None
 
45
 
46
  # ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์œผ๋กœ API ํ‚ค ๋กœ๋“œ ์‹œ๋„
47
  load_dotenv() # .env ํŒŒ์ผ์—์„œ ๋กœ๋“œ ์‹œ๋„
 
49
  # 1. ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ API ํ‚ค ํ™•์ธ
50
  if os.environ.get('OPENAI_API_KEY'):
51
  st.session_state.openai_api_key = os.environ.get('OPENAI_API_KEY')
52
+ openai.api_key = st.session_state.openai_api_key
53
 
54
  # 2. Streamlit secrets์—์„œ API ํ‚ค ํ™•์ธ (try-except๋กœ ์˜ค๋ฅ˜ ๋ฐฉ์ง€)
55
  if not st.session_state.openai_api_key:
56
  try:
57
  if 'OPENAI_API_KEY' in st.secrets:
58
  st.session_state.openai_api_key = st.secrets['OPENAI_API_KEY']
59
+ openai.api_key = st.session_state.openai_api_key
60
  except Exception as e:
61
  pass # secrets ํŒŒ์ผ์ด ์—†์–ด๋„ ์˜ค๋ฅ˜ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
62
 
 
 
 
 
63
  # ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก NLTK ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์„ค์ •
64
  nltk_data_dir = '/tmp/nltk_data'
65
  os.makedirs(nltk_data_dir, exist_ok=True)
 
91
  api_key = st.text_input("OpenAI API ํ‚ค ์ž…๋ ฅ", type="password")
92
  if api_key:
93
  st.session_state.openai_api_key = api_key
94
+ openai.api_key = api_key
95
  st.success("API ํ‚ค๊ฐ€ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค!")
96
 
97
  # ์ €์žฅ๋œ ๊ธฐ์‚ฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ•จ์ˆ˜
 
325
  results['top_keywords'] = []
326
  return results
327
 
328
+ # OpenAI API๋ฅผ ์ด์šฉํ•œ ์ƒˆ ๊ธฐ์‚ฌ ์ƒ์„ฑ (๊ตฌ ๋ฒ„์ „ ๋ฐฉ์‹)
329
  def generate_article(original_content, prompt_text):
330
  try:
331
+ if not st.session_state.openai_api_key:
332
  return "OpenAI API ํ‚ค๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
333
 
334
+ response = openai.ChatCompletion.create(
335
  model="gpt-4.1-mini",
336
  messages=[
337
  {"role": "system", "content": "๋‹น์‹ ์€ ์ „๋ฌธ์ ์ธ ๋‰ด์Šค ๊ธฐ์ž์ž…๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”."},
 
339
  ],
340
  max_tokens=2000
341
  )
342
+ return response.choices[0].message['content']
343
  except Exception as e:
344
  return f"๊ธฐ์‚ฌ ์ƒ์„ฑ ์˜ค๋ฅ˜: {str(e)}"
345
 
346
+ # OpenAI API๋ฅผ ์ด์šฉํ•œ ์ด๋ฏธ์ง€ ์ƒ์„ฑ (๊ตฌ ๋ฒ„์ „ ๋ฐฉ์‹)
347
  def generate_image(prompt):
348
  try:
349
+ if not st.session_state.openai_api_key:
350
  return "OpenAI API ํ‚ค๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
351
 
352
+ response = openai.Image.create(
353
+ prompt=prompt,
354
+ n=1,
355
+ size="1024x1024"
356
  )
357
+ return response['data'][0]['url']
 
 
 
 
 
358
  except Exception as e:
359
  return f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์˜ค๋ฅ˜: {str(e)}"
360
 
 
707
 
708
  elif analysis_type == "๊ฐ์ • ๋ถ„์„":
709
  if st.button("๊ฐ์ • ๋ถ„์„ํ•˜๊ธฐ"):
710
+ if st.session_state.openai_api_key:
711
  with st.spinner("๊ธฐ์‚ฌ์˜ ๊ฐ์ •์„ ๋ถ„์„ ์ค‘์ž…๋‹ˆ๋‹ค..."):
712
  try:
713
+ # ๊ฐ์ • ๋ถ„์„ ํ”„๋กฌํ”„ํŠธ ์„ค์ • (๊ตฌ ๋ฒ„์ „ ๋ฐฉ์‹)
714
+ response = openai.ChatCompletion.create(
715
  model="gpt-4.1-mini",
716
  messages=[
717
  {"role": "system", "content": "๋‹น์‹ ์€ ํ…์ŠคํŠธ์˜ ๊ฐ์ •๊ณผ ๋…ผ์กฐ๋ฅผ ๋ถ„์„ํ•˜๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‰ด์Šค ๊ธฐ์‚ฌ๏ฟฝ๏ฟฝ๏ฟฝ ๊ฐ์ •๊ณผ ๋…ผ์กฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ , '๊ธ์ •์ ', '๋ถ€์ •์ ', '์ค‘๋ฆฝ์ ' ์ค‘ ํ•˜๋‚˜๋กœ ๋ถ„๋ฅ˜ํ•ด ์ฃผ์„ธ์š”. ๋˜ํ•œ ๊ธฐ์‚ฌ์—์„œ ๋“œ๋Ÿฌ๋‚˜๋Š” ํ•ต์‹ฌ ๊ฐ์ • ํ‚ค์›Œ๋“œ๋ฅผ 5๊ฐœ ์ถ”์ถœํ•˜๊ณ , ๊ฐ ํ‚ค์›Œ๋“œ๋ณ„๋กœ 1-10 ์‚ฌ์ด์˜ ๊ฐ•๋„ ์ ์ˆ˜๋ฅผ ๋งค๊ฒจ์ฃผ์„ธ์š”. JSON ํ˜•์‹์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‘๋‹ตํ•ด์ฃผ์„ธ์š”: {'sentiment': '๊ธ์ •์ /๋ถ€์ •์ /์ค‘๋ฆฝ์ ', 'reason': '์ด์œ  ์„ค๋ช…...', 'keywords': [{'word': 'ํ‚ค์›Œ๋“œ1', 'score': 8}, {'word': 'ํ‚ค์›Œ๋“œ2', 'score': 7}, ...]}"},
718
  {"role": "user", "content": f"๋‹ค์Œ ๋‰ด์Šค ๊ธฐ์‚ฌ๋ฅผ ๋ถ„์„ํ•ด ์ฃผ์„ธ์š”:\n\n์ œ๋ชฉ: {selected_article['title']}\n\n๋‚ด์šฉ: {selected_article['content'][:1500]}"}
719
  ],
720
+ max_tokens=800
 
721
  )
722
 
723
+ # JSON ํŒŒ์‹ฑ (๊ตฌ ๋ฒ„์ „ ๋ฐฉ์‹)
724
+ analysis_result = json.loads(response.choices[0].message['content'])
725
 
726
  # ๊ฒฐ๊ณผ ์‹œ๊ฐํ™”
727
  st.subheader("๊ฐ์ • ๋ถ„์„ ๊ฒฐ๊ณผ")
 
907
  generate_image_too = st.checkbox("๊ธฐ์‚ฌ ์ƒ์„ฑ ํ›„ ์ด๋ฏธ์ง€๋„ ํ•จ๊ป˜ ์ƒ์„ฑํ•˜๊ธฐ", value=True)
908
 
909
  if st.button("์ƒˆ ๊ธฐ์‚ฌ ์ƒ์„ฑํ•˜๊ธฐ"):
910
+ if st.session_state.openai_api_key:
911
  with st.spinner("๊ธฐ์‚ฌ๋ฅผ ์ƒ์„ฑ ์ค‘์ž…๋‹ˆ๋‹ค..."):
912
  new_article = generate_article(selected_article['content'], prompt_text)
913