ginipick commited on
Commit
f1ac0c2
Β·
verified Β·
1 Parent(s): 10ec03b

Update app-backup2.py

Browse files
Files changed (1) hide show
  1. app-backup2.py +88 -30
app-backup2.py CHANGED
@@ -16,6 +16,8 @@ from folium.plugins import HeatMap, MarkerCluster
16
  import requests
17
  from collections import Counter
18
  import re
 
 
19
 
20
  # ============================================================================
21
  # 데이터 λ‘œλ” 클래슀
@@ -502,12 +504,16 @@ class MarketAnalyzer:
502
  class LLMQueryProcessor:
503
  """Fireworks AI 기반 μžμ—°μ–΄ 처리"""
504
 
505
- def __init__(self, api_key: str):
506
- self.api_key = api_key
 
507
  self.base_url = "https://api.fireworks.ai/inference/v1/chat/completions"
 
 
 
508
 
509
- def process_query(self, query: str, data_context: Dict, chat_history: List = None) -> str:
510
- """μžμ—°μ–΄ 쿼리 처리"""
511
  system_prompt = f"""당신은 ν•œκ΅­ μƒκΆŒ 데이터 뢄석 μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
512
 
513
  πŸ“Š **ν˜„μž¬ 뢄석 데이터**
@@ -533,14 +539,49 @@ class LLMQueryProcessor:
533
  "Content-Type": "application/json"
534
  }
535
 
536
- try:
537
- response = requests.post(self.base_url, headers=headers, json=payload, timeout=30)
538
- if response.status_code == 200:
539
- return response.json()['choices'][0]['message']['content']
540
- else:
541
- return f"⚠️ API 였λ₯˜: {response.status_code}"
542
- except Exception as e:
543
- return f"❌ 였λ₯˜: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
 
545
 
546
  # ============================================================================
@@ -610,16 +651,17 @@ def generate_insights():
610
  return result[:11]
611
 
612
 
613
- def chat_respond(message, api_key, history):
614
  """챗봇 응닡"""
615
  if app_state.analyzer is None:
616
  return history + [[message, "❌ λ¨Όμ € 데이터λ₯Ό λ‘œλ“œν•΄μ£Όμ„Έμš”!"]]
617
 
618
  data_context = app_state.analyzer.analyze_for_llm()
619
 
620
- if api_key:
621
- if app_state.llm_processor is None or app_state.llm_processor.api_key != api_key:
622
- app_state.llm_processor = LLMQueryProcessor(api_key)
 
623
 
624
  chat_hist = []
625
  for user_msg, bot_msg in history:
@@ -627,8 +669,9 @@ def chat_respond(message, api_key, history):
627
  chat_hist.append({"role": "assistant", "content": bot_msg})
628
 
629
  response = app_state.llm_processor.process_query(message, data_context, chat_hist)
630
- else:
631
- # κΈ°λ³Έ 톡계
 
632
  response = f"""πŸ“Š **κΈ°λ³Έ 데이터 뢄석 κ²°κ³Ό**
633
 
634
  **전체 ν˜„ν™©**
@@ -636,7 +679,13 @@ def chat_respond(message, api_key, history):
636
  - μ—…μ’… μ’…λ₯˜: {data_context['μ—…μ’…_수']}개
637
  - 1μΈ΅ λΉ„οΏ½οΏ½: {data_context.get('1μΈ΅_λΉ„μœ¨', 'N/A')}
638
 
639
- πŸ’‘ API ν‚€λ₯Ό μž…λ ₯ν•˜λ©΄ 더 μƒμ„Έν•œ AI 뢄석을 받을 수 μžˆμŠ΅λ‹ˆλ‹€!"""
 
 
 
 
 
 
640
 
641
  history.append([message, response])
642
  return history
@@ -658,11 +707,9 @@ with gr.Blocks(title="AI μƒκΆŒ 뢄석 μ‹œμŠ€ν…œ Pro", theme=gr.themes.Soft()) a
658
  with gr.Column(scale=1):
659
  gr.Markdown("### βš™οΈ μ„€μ •")
660
 
661
- api_key_input = gr.Textbox(
662
- label="πŸ”‘ Fireworks AI API Key (선택)",
663
- type="password",
664
- placeholder="API ν‚€λ₯Ό μž…λ ₯ν•˜μ„Έμš”"
665
- )
666
 
667
  region_select = gr.CheckboxGroup(
668
  choices=list(MarketDataLoader.REGIONS.keys()),
@@ -742,10 +789,10 @@ with gr.Blocks(title="AI μƒκΆŒ 뢄석 μ‹œμŠ€ν…œ Pro", theme=gr.themes.Soft()) a
742
  outputs=[map_output, chart1, chart2, chart3, chart4, chart5, chart6, chart7, chart8, chart9, chart10]
743
  )
744
 
745
- # 챗봇 이벀트
746
  submit_btn.click(
747
  fn=chat_respond,
748
- inputs=[msg_input, api_key_input, chatbot],
749
  outputs=[chatbot]
750
  ).then(
751
  fn=lambda: "",
@@ -754,7 +801,7 @@ with gr.Blocks(title="AI μƒκΆŒ 뢄석 μ‹œμŠ€ν…œ Pro", theme=gr.themes.Soft()) a
754
 
755
  msg_input.submit(
756
  fn=chat_respond,
757
- inputs=[msg_input, api_key_input, chatbot],
758
  outputs=[chatbot]
759
  ).then(
760
  fn=lambda: "",
@@ -769,14 +816,25 @@ with gr.Blocks(title="AI μƒκΆŒ 뢄석 μ‹œμŠ€ν…œ Pro", theme=gr.themes.Soft()) a
769
  (sample_btn4, "ν”„λžœμ°¨μ΄μ¦ˆ 점유율?")
770
  ]:
771
  btn.click(
772
- fn=lambda t=text, h=chatbot: chat_respond(t, api_key_input.value, h.value or []),
773
  outputs=[chatbot]
774
  )
775
 
776
  gr.Markdown("""
777
  ---
778
  ### πŸ“– μ‚¬μš© κ°€μ΄λ“œ
779
- 1. API ν‚€ μž…λ ₯ (선택) β†’ 2. μ§€μ—­ 선택 β†’ 3. 데이터 λ‘œλ“œ β†’ 4. 10κ°€μ§€ μΈμ‚¬μ΄νŠΈ 확인 λ˜λŠ” AIμ—κ²Œ 질문
 
 
 
 
 
 
 
 
 
 
 
780
 
781
  ### πŸ“Š μ œκ³΅λ˜λŠ” 10κ°€μ§€ 뢄석
782
  1. **업쒅별 점포 수**: κ°€μž₯ λ§Žμ€ μ—…μ’… TOP 15
@@ -790,7 +848,7 @@ with gr.Blocks(title="AI μƒκΆŒ 뢄석 μ‹œμŠ€ν…œ Pro", theme=gr.themes.Soft()) a
790
  9. **μ†ŒλΆ„λ₯˜ νŠΈλ Œλ“œ**: μ„ΈλΆ€ μ—…μ’… 뢄포
791
  10. **μ§€μ—­ νŠΉν™”**: 각 μ§€μ—­μ˜ νŠΉν™” μ—…μ’…
792
 
793
- πŸ’‘ **Tip**: API ν‚€ 없이도 κΈ°λ³Έ 톡계λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€!
794
  """)
795
 
796
  # μ‹€ν–‰
 
16
  import requests
17
  from collections import Counter
18
  import re
19
+ import os
20
+ import time
21
 
22
  # ============================================================================
23
  # 데이터 λ‘œλ” 클래슀
 
504
  class LLMQueryProcessor:
505
  """Fireworks AI 기반 μžμ—°μ–΄ 처리"""
506
 
507
+ def __init__(self, api_key: str = None):
508
+ # ν™˜κ²½λ³€μˆ˜μ—μ„œ API ν‚€ κ°€μ Έμ˜€κΈ°
509
+ self.api_key = api_key or os.getenv("FIREWORKS_API_KEY")
510
  self.base_url = "https://api.fireworks.ai/inference/v1/chat/completions"
511
+
512
+ if not self.api_key:
513
+ raise ValueError("❌ FIREWORKS_API_KEY ν™˜κ²½λ³€μˆ˜λ₯Ό μ„€μ •ν•˜κ±°λ‚˜ API ν‚€λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”!")
514
 
515
+ def process_query(self, query: str, data_context: Dict, chat_history: List = None, max_retries: int = 3) -> str:
516
+ """μžμ—°μ–΄ 쿼리 처리 (μž¬μ‹œλ„ 둜직 포함)"""
517
  system_prompt = f"""당신은 ν•œκ΅­ μƒκΆŒ 데이터 뢄석 μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
518
 
519
  πŸ“Š **ν˜„μž¬ 뢄석 데이터**
 
539
  "Content-Type": "application/json"
540
  }
541
 
542
+ # μž¬μ‹œλ„ 둜직
543
+ for attempt in range(max_retries):
544
+ try:
545
+ # νƒ€μž„μ•„μ›ƒμ„ 60초둜 증가
546
+ response = requests.post(
547
+ self.base_url,
548
+ headers=headers,
549
+ json=payload,
550
+ timeout=60
551
+ )
552
+
553
+ if response.status_code == 200:
554
+ return response.json()['choices'][0]['message']['content']
555
+ elif response.status_code == 429:
556
+ # Rate limit - μž¬μ‹œλ„
557
+ wait_time = (attempt + 1) * 2
558
+ time.sleep(wait_time)
559
+ continue
560
+ else:
561
+ return f"⚠️ API 였λ₯˜: {response.status_code} - {response.text[:200]}"
562
+
563
+ except requests.exceptions.Timeout:
564
+ if attempt < max_retries - 1:
565
+ time.sleep(2)
566
+ continue
567
+ else:
568
+ return "⚠️ API 응닡 μ‹œκ°„ 초과. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."
569
+
570
+ except requests.exceptions.ConnectionError:
571
+ if attempt < max_retries - 1:
572
+ time.sleep(2)
573
+ continue
574
+ else:
575
+ return "⚠️ λ„€νŠΈμ›Œν¬ μ—°κ²° 였λ₯˜. 인터넷 연결을 ν™•μΈν•΄μ£Όμ„Έμš”."
576
+
577
+ except Exception as e:
578
+ if attempt < max_retries - 1:
579
+ time.sleep(1)
580
+ continue
581
+ else:
582
+ return f"❌ 였λ₯˜: {str(e)}"
583
+
584
+ return "⚠️ μ΅œλŒ€ μž¬μ‹œλ„ 횟수 초과. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."
585
 
586
 
587
  # ============================================================================
 
651
  return result[:11]
652
 
653
 
654
+ def chat_respond(message, history):
655
  """챗봇 응닡"""
656
  if app_state.analyzer is None:
657
  return history + [[message, "❌ λ¨Όμ € 데이터λ₯Ό λ‘œλ“œν•΄μ£Όμ„Έμš”!"]]
658
 
659
  data_context = app_state.analyzer.analyze_for_llm()
660
 
661
+ # LLM ν”„λ‘œμ„Έμ„œ μ΄ˆκΈ°ν™” (ν™˜κ²½λ³€μˆ˜μ—μ„œ API ν‚€ μžλ™ λ‘œλ“œ)
662
+ try:
663
+ if app_state.llm_processor is None:
664
+ app_state.llm_processor = LLMQueryProcessor()
665
 
666
  chat_hist = []
667
  for user_msg, bot_msg in history:
 
669
  chat_hist.append({"role": "assistant", "content": bot_msg})
670
 
671
  response = app_state.llm_processor.process_query(message, data_context, chat_hist)
672
+
673
+ except ValueError as e:
674
+ # API ν‚€κ°€ μ—†λŠ” 경우 κΈ°λ³Έ 톡계 제곡
675
  response = f"""πŸ“Š **κΈ°λ³Έ 데이터 뢄석 κ²°κ³Ό**
676
 
677
  **전체 ν˜„ν™©**
 
679
  - μ—…μ’… μ’…λ₯˜: {data_context['μ—…μ’…_수']}개
680
  - 1μΈ΅ λΉ„οΏ½οΏ½: {data_context.get('1μΈ΅_λΉ„μœ¨', 'N/A')}
681
 
682
+ ⚠️ **AI 뢄석 μ‚¬μš© 방법**
683
+ ν™˜κ²½λ³€μˆ˜λ₯Ό μ„€μ •ν•˜μ„Έμš”:
684
+ ```bash
685
+ export FIREWORKS_API_KEY="your_api_key_here"
686
+ ```
687
+
688
+ λ˜λŠ” Hugging Face Spaceμ—μ„œλŠ” Settings > Variables μ—μ„œ μ„€μ •ν•˜μ„Έμš”."""
689
 
690
  history.append([message, response])
691
  return history
 
707
  with gr.Column(scale=1):
708
  gr.Markdown("### βš™οΈ μ„€μ •")
709
 
710
+ # ν™˜κ²½λ³€μˆ˜ μƒνƒœ ν‘œμ‹œ
711
+ api_status = "βœ… API ν‚€ 섀정됨" if os.getenv("FIREWORKS_API_KEY") else "⚠️ API ν‚€ λ―Έμ„€μ • (κΈ°λ³Έ ν†΅κ³„λ§Œ 제곡)"
712
+ gr.Markdown(f"**πŸ”‘ API μƒνƒœ**: {api_status}")
 
 
713
 
714
  region_select = gr.CheckboxGroup(
715
  choices=list(MarketDataLoader.REGIONS.keys()),
 
789
  outputs=[map_output, chart1, chart2, chart3, chart4, chart5, chart6, chart7, chart8, chart9, chart10]
790
  )
791
 
792
+ # 챗봇 이벀트 (API ν‚€ νŒŒλΌλ―Έν„° 제거)
793
  submit_btn.click(
794
  fn=chat_respond,
795
+ inputs=[msg_input, chatbot],
796
  outputs=[chatbot]
797
  ).then(
798
  fn=lambda: "",
 
801
 
802
  msg_input.submit(
803
  fn=chat_respond,
804
+ inputs=[msg_input, chatbot],
805
  outputs=[chatbot]
806
  ).then(
807
  fn=lambda: "",
 
816
  (sample_btn4, "ν”„λžœμ°¨μ΄μ¦ˆ 점유율?")
817
  ]:
818
  btn.click(
819
+ fn=lambda t=text, h=chatbot: chat_respond(t, h.value or []),
820
  outputs=[chatbot]
821
  )
822
 
823
  gr.Markdown("""
824
  ---
825
  ### πŸ“– μ‚¬μš© κ°€μ΄λ“œ
826
+ 1. μ§€μ—­ 선택 β†’ 2. 데이터 λ‘œλ“œ β†’ 3. 10κ°€μ§€ μΈμ‚¬μ΄νŠΈ 확인 λ˜λŠ” AIμ—κ²Œ 질문
827
+
828
+ ### πŸ”‘ AI 챗봇 ν™œμ„±ν™” 방법
829
+ ν™˜κ²½λ³€μˆ˜ μ„€μ •:
830
+ ```bash
831
+ export FIREWORKS_API_KEY="your_api_key_here"
832
+ ```
833
+
834
+ Hugging Face Spaceμ—μ„œλŠ”:
835
+ 1. Settings 메뉴 클릭
836
+ 2. Variables νƒ­ 선택
837
+ 3. New variable μΆ”κ°€: `FIREWORKS_API_KEY`
838
 
839
  ### πŸ“Š μ œκ³΅λ˜λŠ” 10κ°€μ§€ 뢄석
840
  1. **업쒅별 점포 수**: κ°€μž₯ λ§Žμ€ μ—…μ’… TOP 15
 
848
  9. **μ†ŒλΆ„λ₯˜ νŠΈλ Œλ“œ**: μ„ΈλΆ€ μ—…μ’… 뢄포
849
  10. **μ§€μ—­ νŠΉν™”**: 각 μ§€μ—­μ˜ νŠΉν™” μ—…μ’…
850
 
851
+ πŸ’‘ **Tip**: API ν‚€ 없이도 10κ°€μ§€ μ‹œκ°ν™” 뢄석과 κΈ°λ³Έ 톡계λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€!
852
  """)
853
 
854
  # μ‹€ν–‰