fish_reference_audio_sync.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. from typing import List, Dict, Any
  2. import pandas as pd
  3. from tabulate import tabulate
  4. from client.FishClient import FishClient
  5. from helper.MySQLHelper import MySQLHelper
  6. from util import feishu_inform_util
  7. official_fish_client = FishClient("https://api.fish.audio")
  8. mysql_helper = MySQLHelper(
  9. host="rm-t4na9qj85v7790tf84o.mysql.singapore.rds.aliyuncs.com",
  10. username="readonly",
  11. password="HdkZ4TDmeK6SQ3BRtJBk",
  12. database="aigc-admin-prod"
  13. )
  14. webhook_url = "https://open.feishu.cn/open-apis/bot/v2/hook/c09712a8-22cd-4bfa-93a5-30ae7b1db11b"
  15. def df_to_feishu_table(df: pd.DataFrame) -> dict:
  16. """
  17. 将 pandas DataFrame 转换为飞书卡片表格组件
  18. """
  19. # 构建列定义
  20. columns = [{"name": col, "width": "auto"} for col in df.columns]
  21. # 构建行数据
  22. rows = []
  23. for _, row in df.iterrows():
  24. cells = [{"text": str(val)} for val in row.values]
  25. rows.append({"cells": cells})
  26. return {
  27. "tag": "table",
  28. "columns": columns,
  29. "rows": rows
  30. }
  31. def get_fish_pq_ip() -> List[str]:
  32. sql = "select * from base_config where config_key = 'fish_pq_ip_list';"
  33. result = mysql_helper.execute_query(sql)
  34. if not result:
  35. return []
  36. value = result[0]['config_value']
  37. return value.split(',')
  38. def get_all_reference_by_db() -> List[Dict[str, Any]]:
  39. sql = "select * from ai_model_tts where model = 33;"
  40. return mysql_helper.execute_query(sql)
  41. def build_card_json(msg: str):
  42. return {
  43. "config": {},
  44. "i18n_elements": {
  45. "zh_cn": [
  46. {
  47. "tag": "markdown",
  48. "content": "",
  49. "text_align": "left",
  50. "text_size": "normal"
  51. },
  52. {
  53. "tag": "markdown",
  54. "content": f"```\n{msg}\n```",
  55. "text_align": "left",
  56. "text_size": "normal"
  57. }
  58. ]
  59. },
  60. "i18n_header": {
  61. "zh_cn": {
  62. "title": {
  63. "tag": "plain_text",
  64. "content": "特征同步延迟告警"
  65. },
  66. "subtitle": {
  67. "tag": "plain_text",
  68. "content": ""
  69. },
  70. "template": "yellow"
  71. }
  72. }
  73. }
  74. def _main():
  75. db_all_reference = get_all_reference_by_db()
  76. reference_id_and_text_map = {}
  77. all_ip = get_fish_pq_ip()
  78. print(f"当前配置的Fish服务器IP列表为: {all_ip}")
  79. sync_fail_list = []
  80. for ip in all_ip:
  81. print(f"开始将音频同步到实例【{ip}】")
  82. fish_client = FishClient(f"http://{ip}:8080")
  83. exist_references_ids = fish_client.get_all_references_id()
  84. for reference_info in db_all_reference:
  85. reference_id = reference_info['speaker_id']
  86. try:
  87. if reference_id in exist_references_ids:
  88. sync_fail_list.append({
  89. "实例IP": ip,
  90. "音频ID": reference_id,
  91. "失败原因": "同步成功",
  92. })
  93. print(f"音频ID【{reference_id}】在实例【{ip}】上已经存在,跳过")
  94. continue
  95. if reference_id not in reference_id_and_text_map:
  96. model_info = official_fish_client.get_model_info_by_id(reference_id)
  97. text = model_info['samples'][0]['text']
  98. reference_id_and_text_map[reference_id] = text
  99. audio_url = reference_info['audio_url']
  100. reference_text = reference_id_and_text_map[reference_id]
  101. fish_client.add_reference_id_by_url(reference_id=reference_id, reference_text=reference_text, audio_url=audio_url)
  102. print(f"音频ID【{reference_id}】同步到实例【{ip}】上完成")
  103. except Exception as e:
  104. print(f"音频ID【{reference_id}】同步到实例【{ip}】上异常 {str(e)}")
  105. sync_fail_list.append({
  106. "实例IP": ip,
  107. "音频ID": reference_id,
  108. "失败原因": str(e),
  109. })
  110. print(f"将音频同步到实例【{ip}】完成")
  111. # 同步失败的告警通知
  112. df = pd.DataFrame(sync_fail_list)
  113. msg = tabulate(df, headers='keys', tablefmt='grid', showindex=False)
  114. print("同步失败的音频信息")
  115. print(msg)
  116. print("=" * 300)
  117. feishu_inform_util.send_card_msg_to_feishu(
  118. webhook=webhook_url,
  119. card_json=build_card_json(msg)
  120. )
  121. if __name__ == '__main__':
  122. _main()