youngtsai commited on
Commit
fa3af80
·
1 Parent(s): 4ebfa97
Files changed (3) hide show
  1. app.py +131 -3
  2. local_config.json +0 -23
  3. requirements.txt +2 -1
app.py CHANGED
@@ -32,6 +32,7 @@ from googleapiclient.http import MediaIoBaseUpload
32
  from educational_material import EducationalMaterial
33
  from storage_service import GoogleCloudStorage
34
 
 
35
 
36
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
37
  print(f"is_env_local: {is_env_local}")
@@ -45,6 +46,9 @@ if is_env_local:
45
  OPEN_AI_KEY = config["OPEN_AI_KEY"]
46
  GROQ_API_KEY = config["GROQ_API_KEY"]
47
  JUTOR_CHAT_KEY = config["JUTOR_CHAT_KEY"]
 
 
 
48
  OUTPUT_PATH = config["OUTPUT_PATH"]
49
  else:
50
  PASSWORD = os.getenv("PASSWORD")
@@ -53,6 +57,9 @@ else:
53
  OPEN_AI_KEY = os.getenv("OPEN_AI_KEY")
54
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
55
  JUTOR_CHAT_KEY = os.getenv("JUTOR_CHAT_KEY")
 
 
 
56
  OUTPUT_PATH = 'videos'
57
 
58
  TRANSCRIPTS = []
@@ -64,6 +71,20 @@ GROQ_CLIENT = Groq(api_key=GROQ_API_KEY)
64
  GCS_SERVICE = GoogleCloudStorage(GCS_KEY)
65
  GCS_CLIENT = GCS_SERVICE.client
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  # 驗證 password
68
  def verify_password(password):
69
  if password == PASSWORD:
@@ -1615,6 +1636,106 @@ def poll_run_status(run_id, thread_id, timeout=600, poll_interval=5):
1615
 
1616
  return run.status
1617
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1618
  def update_slide(direction):
1619
  global TRANSCRIPTS
1620
  global CURRENT_INDEX
@@ -1743,7 +1864,6 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
1743
  mind_map_html = gr.HTML()
1744
  with gr.Column(scale=2):
1745
  with gr.Tab("OPENAI"):
1746
- gr.Markdown("## OPEN AI 模式")
1747
  bot_avatar = "https://junyi-avatar.s3.ap-northeast-1.amazonaws.com/live/%20%20foxcat-star-18.png?v=20231113095823614"
1748
  user_avatar = "https://junyitopicimg.s3.amazonaws.com/s4byy--icon.jpe?v=20200513013523726"
1749
  chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="OPEN AI", show_share_button=False, likeable=True)
@@ -1753,15 +1873,17 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
1753
  msg = gr.Textbox(label="Message")
1754
  send_button = gr.Button("Send", variant="primary")
1755
  with gr.Tab("GROQ"):
1756
- gr.Markdown("## GROQ 模式")
1757
  groq_chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="groq mode chatbot", show_share_button=False)
1758
  groq_msg = gr.Textbox(label="Message")
1759
  groq_send_button = gr.Button("Send", variant="primary")
1760
  with gr.Tab("JUTOR"):
1761
- gr.Markdown("## JUTOR API 模式")
1762
  jutor_chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="jutor mode chatbot", show_share_button=False)
1763
  jutor_msg = gr.Textbox(label="Message")
1764
  jutor_send_button = gr.Button("Send", variant="primary")
 
 
 
 
1765
 
1766
  with gr.Tab("教師版"):
1767
  with gr.Row():
@@ -1873,6 +1995,12 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
1873
  inputs=[password, jutor_msg, df_string_output, jutor_chatbot, socratic_mode_btn],
1874
  outputs=[jutor_msg, jutor_chatbot]
1875
  )
 
 
 
 
 
 
1876
 
1877
  # 连接按钮点击事件
1878
  chat_with_opan_ai_assistant_input =[password, video_id, thread_id, df_string_output, btn_1, chatbot, content_subject, content_grade, socratic_mode_btn]
 
32
  from educational_material import EducationalMaterial
33
  from storage_service import GoogleCloudStorage
34
 
35
+ import boto3
36
 
37
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
38
  print(f"is_env_local: {is_env_local}")
 
46
  OPEN_AI_KEY = config["OPEN_AI_KEY"]
47
  GROQ_API_KEY = config["GROQ_API_KEY"]
48
  JUTOR_CHAT_KEY = config["JUTOR_CHAT_KEY"]
49
+ AWS_ACCESS_KEY = config["AWS_ACCESS_KEY"]
50
+ AWS_SECRET_KEY = config["AWS_SECRET_KEY"]
51
+ AWS_REGION_NAME = config["AWS_REGION_NAME"]
52
  OUTPUT_PATH = config["OUTPUT_PATH"]
53
  else:
54
  PASSWORD = os.getenv("PASSWORD")
 
57
  OPEN_AI_KEY = os.getenv("OPEN_AI_KEY")
58
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
59
  JUTOR_CHAT_KEY = os.getenv("JUTOR_CHAT_KEY")
60
+ AWS_ACCESS_KEY = os.getenv("AWS_ACCESS_KEY"),
61
+ AWS_SECRET_KEY = os.getenv("AWS_SECRET_KEY"),
62
+ AWS_REGION_NAME = 'us-west-2'
63
  OUTPUT_PATH = 'videos'
64
 
65
  TRANSCRIPTS = []
 
71
  GCS_SERVICE = GoogleCloudStorage(GCS_KEY)
72
  GCS_CLIENT = GCS_SERVICE.client
73
 
74
+
75
+
76
+ # 初始化 boto3 session
77
+ boto3.setup_default_session(
78
+ aws_access_key_id=AWS_ACCESS_KEY,
79
+ aws_secret_access_key=AWS_SECRET_KEY,
80
+ region_name=AWS_REGION_NAME
81
+ )
82
+
83
+ BEDROCK_CLIENT = boto3.client(
84
+ service_name="bedrock-runtime",
85
+ region_name=AWS_REGION_NAME
86
+ )
87
+
88
  # 驗證 password
89
  def verify_password(password):
90
  if password == PASSWORD:
 
1636
 
1637
  return run.status
1638
 
1639
+ def chat_with_claude3(password, user_message, data, chat_history, socratic_mode=False):
1640
+ verify_password(password)
1641
+ data_json = json.loads(data)
1642
+ for entry in data_json:
1643
+ entry.pop('embed_url', None) # Remove 'embed_url' if it exists
1644
+ entry.pop('screenshot_path', None)
1645
+
1646
+ if socratic_mode:
1647
+ sys_content = f"""
1648
+ 你是一個擅長資料分析跟影片教學的老師,user 為學生
1649
+ 請用 {data} 為資料文本,自行判斷資料的種類,
1650
+ 並進行對話,使用 台灣人的口與表達,及繁體中文zh-TW
1651
+ 請你用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1652
+ 不要直接給予答案,讓學生自己思考
1653
+ 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1654
+
1655
+ 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1656
+ 或者你可以問學生一些問題,幫助學生更好的理解資料
1657
+
1658
+ 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1659
+
1660
+ 最後,在你回答的開頭標註【蘇格拉底助教】
1661
+ """
1662
+ else:
1663
+ sys_content = f"""
1664
+ 你是一個擅長資料分析跟影片教學的老師,user 為學生
1665
+ 請用 {data} 為資料文本,自行判斷資料的種類,
1666
+ 並進行對話,使用 zh-TW
1667
+
1668
+ 如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1669
+ 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生可以找到相對應的時間點
1670
+
1671
+ 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1672
+ 或者你可以問學生一些問題,幫助學生更好的理解資料
1673
+
1674
+ 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1675
+ """
1676
+
1677
+ messages = []
1678
+
1679
+ # if chat_history is not none, append role, content to messages
1680
+ # chat_history = [(user, assistant), (user, assistant), ...]
1681
+ # In the list, first one is user, then assistant
1682
+ if chat_history is not None:
1683
+ # 如果超過10則訊息,只保留最後10則訊息
1684
+ if len(chat_history) > 10:
1685
+ chat_history = chat_history[-10:]
1686
+
1687
+ for chat in chat_history:
1688
+ old_messages = [
1689
+ {"role": "user", "content": chat[0]},
1690
+ {"role": "assistant", "content": chat[1]}
1691
+ ]
1692
+ messages += old_messages
1693
+ else:
1694
+ pass
1695
+
1696
+ messages.append({"role": "user", "content": user_message})
1697
+ model_id = "anthropic.claude-3-sonnet-20240229-v1:0"
1698
+ # model_id = "anthropic.claude-3-haiku-20240307-v1:0"
1699
+ kwargs = {
1700
+ "modelId": model_id,
1701
+ "contentType": "application/json",
1702
+ "accept": "application/json",
1703
+ "body": json.dumps({
1704
+ "anthropic_version": "bedrock-2023-05-31",
1705
+ "max_tokens": 1000,
1706
+ "system": sys_content,
1707
+ "messages": messages
1708
+ })
1709
+ }
1710
+ # 建立 message API,讀取回應
1711
+ response = BEDROCK_CLIENT.invoke_model(**kwargs)
1712
+
1713
+ if response:
1714
+ # 处理响应数据
1715
+ response_body = json.loads(response.get('body').read())
1716
+ response_completion = response_body.get('content')[0].get('text').strip()
1717
+ # 更新聊天历史
1718
+ new_chat_history = (user_message, response_completion)
1719
+ if chat_history is None:
1720
+ chat_history = [new_chat_history]
1721
+ else:
1722
+ chat_history.append(new_chat_history)
1723
+
1724
+ # 返回聊天历史和空字符串清空输入框
1725
+ return "", chat_history
1726
+ else:
1727
+ # 处理错误情况
1728
+ print(f"Error: {response.status_code}")
1729
+ return "请求失败,请稍后再试!", chat_history
1730
+
1731
+
1732
+
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
  def update_slide(direction):
1740
  global TRANSCRIPTS
1741
  global CURRENT_INDEX
 
1864
  mind_map_html = gr.HTML()
1865
  with gr.Column(scale=2):
1866
  with gr.Tab("OPENAI"):
 
1867
  bot_avatar = "https://junyi-avatar.s3.ap-northeast-1.amazonaws.com/live/%20%20foxcat-star-18.png?v=20231113095823614"
1868
  user_avatar = "https://junyitopicimg.s3.amazonaws.com/s4byy--icon.jpe?v=20200513013523726"
1869
  chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="OPEN AI", show_share_button=False, likeable=True)
 
1873
  msg = gr.Textbox(label="Message")
1874
  send_button = gr.Button("Send", variant="primary")
1875
  with gr.Tab("GROQ"):
 
1876
  groq_chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="groq mode chatbot", show_share_button=False)
1877
  groq_msg = gr.Textbox(label="Message")
1878
  groq_send_button = gr.Button("Send", variant="primary")
1879
  with gr.Tab("JUTOR"):
 
1880
  jutor_chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="jutor mode chatbot", show_share_button=False)
1881
  jutor_msg = gr.Textbox(label="Message")
1882
  jutor_send_button = gr.Button("Send", variant="primary")
1883
+ with gr.Tab("CLAUDE"):
1884
+ claude_chatbot = gr.Chatbot(avatar_images=[bot_avatar, user_avatar], label="claude mode chatbot", show_share_button=False)
1885
+ claude_msg = gr.Textbox(label="Message")
1886
+ claude_send_button = gr.Button("Send", variant="primary")
1887
 
1888
  with gr.Tab("教師版"):
1889
  with gr.Row():
 
1995
  inputs=[password, jutor_msg, df_string_output, jutor_chatbot, socratic_mode_btn],
1996
  outputs=[jutor_msg, jutor_chatbot]
1997
  )
1998
+ # CLAUDE 模式
1999
+ claude_send_button.click(
2000
+ chat_with_claude3,
2001
+ inputs=[password, claude_msg, df_string_output, claude_chatbot, socratic_mode_btn],
2002
+ outputs=[claude_msg, claude_chatbot]
2003
+ )
2004
 
2005
  # 连接按钮点击事件
2006
  chat_with_opan_ai_assistant_input =[password, video_id, thread_id, df_string_output, btn_1, chatbot, content_subject, content_grade, socratic_mode_btn]
local_config.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "OUTPUT_PATH": "/Users/young/Downloads",
3
- "TRANSCRIPTS": [],
4
- "CURRENT_INDEX": 0,
5
- "VIDEO_ID": "",
6
- "PASSWORD": "6161",
7
- "OPEN_AI_KEY": "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",
8
- "GROQ_API_KEY": "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",
9
- "JUTOR_CHAT_KEY": "b4c318b8d6f770e10163436e0e868b806f50f34ae57f378e78956fb76b41fd27",
10
- "GOOGLE_APPLICATION_CREDENTIALS_JSON": {
11
- "type": "service_account",
12
- "project_id": "junyiacademy",
13
- "private_key_id": "95d4580de7518ff96be219626c58b23f1754ec6a",
14
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmo3M8Ix46FLNS\nX8NGnEMiZBomXQOEfKCRUy0khm5IKgu5RUIWSF/0UuZeWXG93a1PMarBWokTTIpo\njtRNuEAh+H8lbacJ/G6EH5PxyMjPAOROXLvSJUg4c6lOFp/WoFlnirSPsD/YHL3l\nKKm6//h/tN7GDhaqOKrf9xJ1IlSt7odhCgcR7r3dF/+pbZ2UMDA0rmNmj2aJq7rl\n1qOD/8yC3ainledRRSt8oE7t4w+3eqI5GO7OdLiNwSxGGBNx9IiJln6TFC7frvET\nzr2ZUVLL7jFdWNyfXPU3/B+7JwyXgFGfHpiyQ2xyFAUR62HkpVxs0bKNbnLLmKoL\nIXCQ+lB9AgMBAAECggEAAJLA1C/E7E46SeEqdP3o/TbAwy+Ro4dnUaRNbaK9HmJv\nXymcYJc/JfxjBcRu0qV6wyaeaH1UVZJ67TtWX6JvuPQDWQ2dVX5eovW42aks/AlR\n1wSgeA5rr7pkrZ6jZWa2XGNfOLxpwaGpIqrcx7T/ija/Qc8qmShnSyx+awi9YdX4\n/ih1Ug1fqHPQ1j3Xx23J/S4Wb6eamJZ1BW+txZUUVD2KFnw7iJWR81ceTIuoSY4R\na3Vd8yB1Ri9iVaP6pe0WeA14VfU1d3tbO0GRF6XsEtdRynVXA17nO6okc3yV0bOQ\nnWqibtfT6AWmJFIyya3DrZDxKqSFNuVfHaJrO2LvwQKBgQDRGUzCYJpGw6NAQuKw\n3egfBoTjozZxjykZb0GFFRCIIE9AmX0PkCbz9bxjjMtb9pTH3aVIiv8mL3rfqzdK\nEPEfyC5TntWqahqBW+fOMrpnU54o4Ji1TlFuSBMRBxqIPcJnKFuttkfPZiHbxe3i\nkeqBbJ4HafH5ZNAV+pHwQKSXDwKBgQDMBAbxvSKgYXxeGMOs62rK6y9NeZlKpRUJ\nORdBv+3sLTwSjlpEPwn/KgMXHaHnpDXhtTDP0ad9nLOKnZ5k8dRNcpyUEXVC2WTD\nDHd37lChG0XRnfGuxIvfr5ZYajN/sIgV8WuNpFuWnFj+mGdi+OpzS+KG3J2rMx/k\n4jl1l8g/swKBgQCYJCVyxSFb3dt51XDmKgBMGs00aLwjcnwAErCEqagGtCOWKFgT\nq9p75dA2SupotojYyBAMMX6nBSMNfaHUFXGso1X55/clcOBqQTnwEX8J0ZChw5G5\nUgv0ByNAX3/Ro8ZAkt/qDFhBstlt9J07HtqXYzW0xUSYJt81LsVjH1XixwKBgDF6\nUIzUB8/JlLXlX59SQMYRn5k0gl6+BooEFIXXnEYI+matq2qdtzjw4Wr7vsZE5uRk\nYwAjonEuTcSyUTW+CHT39M1cJood2vgKz/aAD4Hi8V3S5kgyVpHbLaUnrHGtSHO5\n5xGk6KlwJY0pPPmd0I5BuyBl5L8eWP/TdYf1VZVNAoGAUEMSVxBd/onX5LXrzkR7\nOS8w6L+YL68yWCFs1pocfY+cZfkBpteLXzqOMKN2Xc3C7TGGySnEaQlG8bF1P00E\nW9HZvrSYbhsZwEKiIxY3suWRMPRlbeHU9hxt7rYPM+kwl8zy+Z/UtE28Zwhcr0+r\n7EkfwiOEvYStw0mJ9xwhiwU=\n-----END PRIVATE KEY-----\n",
15
- "client_email": "analytics-api@junyiacademy.iam.gserviceaccount.com",
16
- "client_id": "113360448655635325414",
17
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
18
- "token_uri": "https://oauth2.googleapis.com/token",
19
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
20
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/analytics-api%40junyiacademy.iam.gserviceaccount.com",
21
- "universe_domain": "googleapis.com"
22
- }
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -15,4 +15,5 @@ google-cloud-storage
15
  groq
16
  yt_dlp
17
  uuid
18
- gtts
 
 
15
  groq
16
  yt_dlp
17
  uuid
18
+ gtts
19
+ boto3