config.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. from pydantic_settings import BaseSettings
  2. import yaml
  3. from pathlib import Path
  4. class AppConfig(BaseSettings):
  5. name: str = "shudao-chat-py"
  6. host: str = "0.0.0.0"
  7. port: int = 22001
  8. debug: bool = True
  9. class DatabaseConfig(BaseSettings):
  10. user: str
  11. password: str
  12. host: str
  13. port: int
  14. database: str
  15. pool_size: int = 100
  16. max_overflow: int = 10
  17. pool_recycle: int = 3600
  18. class DeepSeekConfig(BaseSettings):
  19. api_key: str
  20. api_url: str
  21. class Qwen3Config(BaseSettings):
  22. api_url: str
  23. model: str
  24. class IntentConfig(BaseSettings):
  25. api_url: str
  26. model: str
  27. class YoloConfig(BaseSettings):
  28. base_url: str
  29. class SearchConfig(BaseSettings):
  30. api_url: str
  31. heartbeat_url: str
  32. class DifyConfig(BaseSettings):
  33. workflow_url: str
  34. workflow_id: str
  35. auth_token: str
  36. class AuthConfig(BaseSettings):
  37. api_url: str
  38. class OSSConfig(BaseSettings):
  39. access_key_id: str
  40. access_key_secret: str
  41. bucket: str
  42. endpoint: str
  43. parse_encrypt_key: str
  44. class AIChatConfig(BaseSettings):
  45. api_url: str = "http://127.0.0.1:28002/api/v1"
  46. timeout: int = 600
  47. class SpeechProcurementConfig(BaseSettings):
  48. required_cloud_products: list[str] = [
  49. "asr_sentence_recognition",
  50. "asr_flash_file_recognition",
  51. "tts_text_to_voice",
  52. "tts_long_text",
  53. ]
  54. required_credentials: list[str] = [
  55. "app_id",
  56. "secret_id",
  57. "secret_key",
  58. ]
  59. optional_cloud_products: list[str] = [
  60. "cos",
  61. ]
  62. notes: list[str] = [
  63. "sentence_recognition_for_audio_within_60s_and_3mb",
  64. "flash_file_recognition_for_longer_audio_fallback",
  65. "text_to_voice_for_default_tts",
  66. "long_text_tts_for_content_over_150_chinese_chars",
  67. ]
  68. class SpeechTencentConfig(BaseSettings):
  69. app_id: str = ""
  70. secret_id: str = ""
  71. secret_key: str = ""
  72. region: str = "ap-guangzhou"
  73. asr_endpoint: str = "asr.tencentcloudapi.com"
  74. tts_endpoint: str = "tts.tencentcloudapi.com"
  75. class SpeechTranscribeConfig(BaseSettings):
  76. enabled: bool = True
  77. default_api: str = "SentenceRecognition"
  78. fallback_api: str = "CreateRecTask"
  79. engine_model_type: str = "16k_zh"
  80. source_type: int = 1
  81. voice_format: str = "wav"
  82. input_sample_rate: int = 16000
  83. max_audio_seconds: int = 60
  84. max_audio_size_mb: int = 3
  85. word_info: int = 0
  86. filter_dirty: int = 0
  87. filter_modal: int = 0
  88. filter_punc: int = 0
  89. convert_num_mode: int = 1
  90. hotword_list: str = ""
  91. hotword_id: str = ""
  92. customization_id: str = ""
  93. replace_text_id: str = ""
  94. class SpeechSynthesizeConfig(BaseSettings):
  95. enabled: bool = True
  96. default_api: str = "TextToVoice"
  97. fallback_api: str = "CreateTtsTask"
  98. primary_language: int = 1
  99. voice_type: int = 1001
  100. sample_rate: int = 16000
  101. codec: str = "mp3"
  102. speed: float = 0.0
  103. volume: float = 0.0
  104. enable_subtitle: bool = False
  105. segment_rate: int = 0
  106. emotion_category: str = ""
  107. emotion_intensity: int = 100
  108. basic_text_limit_chars: int = 150
  109. long_text_trigger_chars: int = 120
  110. long_text_max_chars: int = 100000
  111. long_text_codec: str = "mp3"
  112. callback_url: str = ""
  113. class SpeechConfig(BaseSettings):
  114. enabled: bool = True
  115. provider: str = "tencent_cloud"
  116. integration_mode: str = "backend_direct"
  117. backend_service: str = "shudao-chat-py"
  118. request_timeout_seconds: int = 60
  119. procurement: SpeechProcurementConfig = SpeechProcurementConfig()
  120. tencent: SpeechTencentConfig = SpeechTencentConfig()
  121. transcribe: SpeechTranscribeConfig = SpeechTranscribeConfig()
  122. synthesize: SpeechSynthesizeConfig = SpeechSynthesizeConfig()
  123. class ThinkingSummaryConfig(BaseSettings):
  124. """思考过程二次总结(方案三)配置"""
  125. enabled: bool = True
  126. max_points: int = 5
  127. max_input_chars: int = 1500
  128. max_output_chars: int = 600
  129. temperature: float = 0.2
  130. class Settings:
  131. def __init__(self, config_path: str = "config.yaml"):
  132. # 获取项目根目录
  133. if not Path(config_path).is_absolute():
  134. # 相对于当前文件的路径
  135. current_dir = Path(__file__).parent.parent
  136. config_file = current_dir / config_path
  137. else:
  138. config_file = Path(config_path)
  139. if config_file.exists():
  140. with open(config_file, 'r', encoding='utf-8') as f:
  141. config_data = yaml.safe_load(f)
  142. else:
  143. raise FileNotFoundError(f"配置文件不存在: {config_file}")
  144. self.app = AppConfig(**config_data.get('app', {}))
  145. self.database = DatabaseConfig(**config_data.get('database', {}))
  146. self.deepseek = DeepSeekConfig(**config_data.get('deepseek', {}))
  147. self.qwen3 = Qwen3Config(**config_data.get('qwen3', {}))
  148. self.intent = IntentConfig(**config_data.get('intent', {}))
  149. self.yolo = YoloConfig(**config_data.get('yolo', {}))
  150. self.search = SearchConfig(**config_data.get('search', {}))
  151. self.dify = DifyConfig(**config_data.get('dify', {}))
  152. self.auth = AuthConfig(**config_data.get('auth', {}))
  153. self.oss = OSSConfig(**config_data.get('oss', {}))
  154. self.aichat = AIChatConfig(**config_data.get('aichat', {}))
  155. self.speech = SpeechConfig(**config_data.get('speech', {}))
  156. self.thinking_summary = ThinkingSummaryConfig(
  157. **config_data.get('thinking_summary', {}))
  158. self.base_url = config_data.get(
  159. 'base_url', 'https://aqai.shudaodsj.com:22001')
  160. settings = Settings()
  161. def get_base_url() -> str:
  162. return settings.base_url
  163. def get_proxy_url(original_url: str) -> str:
  164. """将原始URL转换为代理URL(加密)"""
  165. if not original_url:
  166. return ""
  167. from .crypto import encrypt_url
  168. encrypted = encrypt_url(original_url)
  169. return f"{settings.base_url}/apiv1/oss/parse?url={encrypted}"