Kims12 commited on
Commit
182e12f
ยท
verified ยท
1 Parent(s): c242fd9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -15
app.py CHANGED
@@ -12,6 +12,7 @@ import time
12
  import hmac
13
  import hashlib
14
  import base64
 
15
 
16
  # ๋””๋ฒ„๊น…(๋กœ๊ทธ)์šฉ ํ•จ์ˆ˜
17
  def debug_log(message: str):
@@ -126,7 +127,7 @@ def analyze_text(text: str):
126
 
127
  return df, temp_file.name
128
 
129
- # [์ฐธ์กฐ์ฝ”๋“œ-2] ๋„ค์ด๋ฒ„ ๊ด‘๊ณ  API ๋ฐ ๊ฒ€์ƒ‰๋Ÿ‰/๋ธ”๋กœ๊ทธ๋ฌธ์„œ์ˆ˜ ์กฐํšŒ ๊ธฐ๋Šฅ
130
  def generate_signature(timestamp, method, uri, secret_key):
131
  message = f"{timestamp}.{method}.{uri}"
132
  digest = hmac.new(secret_key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).digest()
@@ -143,7 +144,7 @@ def get_header(method, uri, api_key, secret_key, customer_id):
143
  "X-Signature": signature
144
  }
145
 
146
- # ๊ธฐ์กด์˜ ๋‹จ์ผ ํ‚ค์›Œ๋“œ์šฉ ํ•จ์ˆ˜ (์ฐธ๊ณ ์šฉ)
147
  def fetch_related_keywords(keyword):
148
  debug_log(f"fetch_related_keywords ํ˜ธ์ถœ, ํ‚ค์›Œ๋“œ: {keyword}")
149
  API_KEY = os.environ["NAVER_API_KEY"]
@@ -191,8 +192,9 @@ def fetch_related_keywords_batch(keywords: list):
191
  uri = "/keywordstool"
192
  method = "GET"
193
  headers = get_header(method, uri, API_KEY, SECRET_KEY, CUSTOMER_ID)
 
194
  params = {
195
- "hintKeywords": keywords, # ๊ทธ๋ฃน์œผ๋กœ ์ „๋‹ฌ (์ตœ๋Œ€ 10๊ฐœ)
196
  "showDetail": "1"
197
  }
198
  response = requests.get(BASE_URL + uri, params=params, headers=headers)
@@ -217,28 +219,40 @@ def fetch_related_keywords_batch(keywords: list):
217
  debug_log("fetch_related_keywords_batch ์™„๋ฃŒ")
218
  return result_df
219
 
220
- # ๊ธฐ์กด process_keyword ํ•จ์ˆ˜๋ฅผ ๊ทธ๋ฃน๋ณ„๋กœ 10๊ฐœ์”ฉ ๋ฌถ์–ด ์ฒ˜๋ฆฌํ•˜๋„๋ก ์ˆ˜์ •
221
  def process_keyword(keywords: str, include_related: bool):
222
  debug_log(f"process_keyword ํ˜ธ์ถœ, ํ‚ค์›Œ๋“œ๋“ค: {keywords}, ์—ฐ๊ด€๊ฒ€์ƒ‰์–ด ํฌํ•จ: {include_related}")
223
  input_keywords = [k.strip() for k in keywords.splitlines() if k.strip()]
 
224
  result_dfs = []
225
-
226
- # ์ž…๋ ฅ๋œ ํ‚ค์›Œ๋“œ๋ฅผ 10๊ฐœ์”ฉ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ธฐ
227
- for i in range(0, len(input_keywords), 10):
228
- batch = input_keywords[i:i+10]
229
- df_batch = fetch_related_keywords_batch(batch)
230
- if df_batch.empty:
 
 
 
 
 
 
 
 
 
 
 
231
  continue
232
- # ๊ฐ ๊ทธ๋ฃน ๋‚ด์—์„œ ์ž…๋ ฅ ํ‚ค์›Œ๋“œ์™€ ์ผ์น˜ํ•˜๋Š” ํ–‰ ์ถ”์ถœ
233
- for kw in batch:
234
  row_kw = df_batch[df_batch["์ •๋ณดํ‚ค์›Œ๋“œ"] == kw]
235
  if not row_kw.empty:
236
  result_dfs.append(row_kw)
237
  else:
238
  result_dfs.append(df_batch.head(1))
239
- # ์ฒซ ๊ทธ๋ฃน์˜ ๊ฒฝ์šฐ ์—ฐ๊ด€๊ฒ€์ƒ‰์–ด ์˜ต์…˜ ์ ์šฉ (์ฒซ ํ‚ค์›Œ๋“œ ์ œ์™ธ)
240
- if include_related and i == 0:
241
- first_keyword = batch[0]
242
  df_related = df_batch[df_batch["์ •๋ณดํ‚ค์›Œ๋“œ"] != first_keyword]
243
  if not df_related.empty:
244
  result_dfs.append(df_related)
 
12
  import hmac
13
  import hashlib
14
  import base64
15
+ import concurrent.futures # ๋™์‹œ ์‹คํ–‰์„ ์œ„ํ•œ ๋ชจ๋“ˆ
16
 
17
  # ๋””๋ฒ„๊น…(๋กœ๊ทธ)์šฉ ํ•จ์ˆ˜
18
  def debug_log(message: str):
 
127
 
128
  return df, temp_file.name
129
 
130
+ # [์ฐธ์กฐ์ฝ”๋“œ-2] ๋„ค์ด๋ฒ„ ๊ด‘๊ณ  API: ์„œ๋ช… ์ƒ์„ฑ ๋ฐ ํ—ค๋” ๊ตฌ์„ฑ
131
  def generate_signature(timestamp, method, uri, secret_key):
132
  message = f"{timestamp}.{method}.{uri}"
133
  digest = hmac.new(secret_key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).digest()
 
144
  "X-Signature": signature
145
  }
146
 
147
+ # ๊ธฐ์กด ๋‹จ์ผ ํ‚ค์›Œ๋“œ์šฉ ํ•จ์ˆ˜ (์ฐธ์กฐ์šฉ)
148
  def fetch_related_keywords(keyword):
149
  debug_log(f"fetch_related_keywords ํ˜ธ์ถœ, ํ‚ค์›Œ๋“œ: {keyword}")
150
  API_KEY = os.environ["NAVER_API_KEY"]
 
192
  uri = "/keywordstool"
193
  method = "GET"
194
  headers = get_header(method, uri, API_KEY, SECRET_KEY, CUSTOMER_ID)
195
+ # API์— ์—ฌ๋Ÿฌ ํ‚ค์›Œ๋“œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋Š” ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ
196
  params = {
197
+ "hintKeywords": keywords,
198
  "showDetail": "1"
199
  }
200
  response = requests.get(BASE_URL + uri, params=params, headers=headers)
 
219
  debug_log("fetch_related_keywords_batch ์™„๋ฃŒ")
220
  return result_df
221
 
222
+ # process_keyword ํ•จ์ˆ˜๋ฅผ ๋™์‹œ ์‹คํ–‰์œผ๋กœ ๊ฐ ๊ทธ๋ฃน(์ตœ๋Œ€ 10๊ฐœ์”ฉ)์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์”ฉ API ํ˜ธ์ถœํ•˜๋„๋ก ๊ฐœ์„ 
223
  def process_keyword(keywords: str, include_related: bool):
224
  debug_log(f"process_keyword ํ˜ธ์ถœ, ํ‚ค์›Œ๋“œ๋“ค: {keywords}, ์—ฐ๊ด€๊ฒ€์ƒ‰์–ด ํฌํ•จ: {include_related}")
225
  input_keywords = [k.strip() for k in keywords.splitlines() if k.strip()]
226
+ groups = [input_keywords[i:i+10] for i in range(0, len(input_keywords), 10)]
227
  result_dfs = []
228
+ group_results = {}
229
+
230
+ # ๊ทธ๋ฃน๋ณ„ API ํ˜ธ์ถœ์„ ๋™์‹œ ์‹คํ–‰
231
+ with concurrent.futures.ThreadPoolExecutor() as executor:
232
+ future_to_group = {executor.submit(fetch_related_keywords_batch, group): group for group in groups}
233
+ for future in concurrent.futures.as_completed(future_to_group):
234
+ group = future_to_group[future]
235
+ try:
236
+ df_batch = future.result()
237
+ group_results[tuple(group)] = df_batch
238
+ except Exception as exc:
239
+ debug_log(f"๊ทธ๋ฃน {group}์—์„œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {exc}")
240
+
241
+ # ๊ฐ ๊ทธ๋ฃน์˜ ๊ฒฐ๊ณผ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌ
242
+ for idx, group in enumerate(groups):
243
+ df_batch = group_results.get(tuple(group))
244
+ if df_batch is None or df_batch.empty:
245
  continue
246
+ # ๊ทธ๋ฃน ๋‚ด ๊ฐ ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•ด ๊ฒฐ๊ณผ ์ถ”์ถœ
247
+ for kw in group:
248
  row_kw = df_batch[df_batch["์ •๋ณดํ‚ค์›Œ๋“œ"] == kw]
249
  if not row_kw.empty:
250
  result_dfs.append(row_kw)
251
  else:
252
  result_dfs.append(df_batch.head(1))
253
+ # ์ฒซ ๋ฒˆ์งธ ๊ทธ๋ฃน์— ๋Œ€ํ•ด ์—ฐ๊ด€๊ฒ€์ƒ‰์–ด ์˜ต์…˜ ์ ์šฉ (์ฒซ ํ‚ค์›Œ๋“œ ์ œ์™ธ)
254
+ if include_related and idx == 0:
255
+ first_keyword = group[0]
256
  df_related = df_batch[df_batch["์ •๋ณดํ‚ค์›Œ๋“œ"] != first_keyword]
257
  if not df_related.empty:
258
  result_dfs.append(df_related)