| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- from pydantic_settings import BaseSettings
- import yaml
- from pathlib import Path
- class AppConfig(BaseSettings):
- name: str = "shudao-chat-py"
- host: str = "0.0.0.0"
- port: int = 22001
- debug: bool = True
- class DatabaseConfig(BaseSettings):
- user: str
- password: str
- host: str
- port: int
- database: str
- pool_size: int = 100
- max_overflow: int = 10
- pool_recycle: int = 3600
- class DeepSeekConfig(BaseSettings):
- api_key: str
- api_url: str
- class Qwen3Config(BaseSettings):
- api_url: str
- model: str
- class IntentConfig(BaseSettings):
- api_url: str
- model: str
- class YoloConfig(BaseSettings):
- base_url: str
- class DifyConfig(BaseSettings):
- workflow_url: str
- workflow_id: str
- auth_token: str
- class AuthConfig(BaseSettings):
- api_url: str
- class OSSConfig(BaseSettings):
- access_key_id: str
- access_key_secret: str
- bucket: str
- endpoint: str
- parse_encrypt_key: str
- class AIChatConfig(BaseSettings):
- api_url: str = "http://127.0.0.1:28002/api/v1"
- timeout: int = 600
- class SpeechProcurementConfig(BaseSettings):
- required_cloud_products: list[str] = [
- "asr_sentence_recognition",
- "asr_flash_file_recognition",
- "tts_text_to_voice",
- "tts_long_text",
- ]
- required_credentials: list[str] = [
- "app_id",
- "secret_id",
- "secret_key",
- ]
- optional_cloud_products: list[str] = [
- "cos",
- ]
- notes: list[str] = [
- "sentence_recognition_for_audio_within_60s_and_3mb",
- "flash_file_recognition_for_longer_audio_fallback",
- "text_to_voice_for_default_tts",
- "long_text_tts_for_content_over_150_chinese_chars",
- ]
- class SpeechTencentConfig(BaseSettings):
- app_id: str = ""
- secret_id: str = ""
- secret_key: str = ""
- region: str = "ap-guangzhou"
- asr_endpoint: str = "asr.tencentcloudapi.com"
- tts_endpoint: str = "tts.tencentcloudapi.com"
- class SpeechTranscribeConfig(BaseSettings):
- enabled: bool = True
- default_api: str = "SentenceRecognition"
- fallback_api: str = "CreateRecTask"
- engine_model_type: str = "16k_zh"
- source_type: int = 1
- voice_format: str = "wav"
- input_sample_rate: int = 16000
- max_audio_seconds: int = 60
- max_audio_size_mb: int = 3
- word_info: int = 0
- filter_dirty: int = 0
- filter_modal: int = 0
- filter_punc: int = 0
- convert_num_mode: int = 1
- hotword_list: str = ""
- hotword_id: str = ""
- customization_id: str = ""
- replace_text_id: str = ""
- class SpeechSynthesizeConfig(BaseSettings):
- enabled: bool = True
- default_api: str = "TextToVoice"
- fallback_api: str = "CreateTtsTask"
- primary_language: int = 1
- voice_type: int = 1001
- sample_rate: int = 16000
- codec: str = "mp3"
- speed: float = 0.0
- volume: float = 0.0
- enable_subtitle: bool = False
- segment_rate: int = 0
- emotion_category: str = ""
- emotion_intensity: int = 100
- basic_text_limit_chars: int = 150
- long_text_trigger_chars: int = 120
- long_text_max_chars: int = 100000
- long_text_codec: str = "mp3"
- callback_url: str = ""
- class SpeechConfig(BaseSettings):
- enabled: bool = True
- provider: str = "tencent_cloud"
- integration_mode: str = "backend_direct"
- backend_service: str = "shudao-chat-py"
- request_timeout_seconds: int = 60
- procurement: SpeechProcurementConfig = SpeechProcurementConfig()
- tencent: SpeechTencentConfig = SpeechTencentConfig()
- transcribe: SpeechTranscribeConfig = SpeechTranscribeConfig()
- synthesize: SpeechSynthesizeConfig = SpeechSynthesizeConfig()
- class ThinkingSummaryConfig(BaseSettings):
- """思考过程二次总结(方案三)配置"""
- enabled: bool = True
- max_points: int = 5
- max_input_chars: int = 1500
- max_output_chars: int = 600
- temperature: float = 0.2
- class Settings:
- def __init__(self, config_path: str = "config.yaml"):
- # 获取项目根目录
- if not Path(config_path).is_absolute():
- # 相对于当前文件的路径
- current_dir = Path(__file__).parent.parent
- config_file = current_dir / config_path
- else:
- config_file = Path(config_path)
- if config_file.exists():
- with open(config_file, 'r', encoding='utf-8') as f:
- config_data = yaml.safe_load(f)
- else:
- raise FileNotFoundError(f"配置文件不存在: {config_file}")
- self.app = AppConfig(**config_data.get('app', {}))
- self.database = DatabaseConfig(**config_data.get('database', {}))
- self.deepseek = DeepSeekConfig(**config_data.get('deepseek', {}))
- self.qwen3 = Qwen3Config(**config_data.get('qwen3', {}))
- self.intent = IntentConfig(**config_data.get('intent', {}))
- self.yolo = YoloConfig(**config_data.get('yolo', {}))
- self.dify = DifyConfig(**config_data.get('dify', {}))
- self.auth = AuthConfig(**config_data.get('auth', {}))
- self.oss = OSSConfig(**config_data.get('oss', {}))
- self.aichat = AIChatConfig(**config_data.get('aichat', {}))
- self.speech = SpeechConfig(**config_data.get('speech', {}))
- self.thinking_summary = ThinkingSummaryConfig(
- **config_data.get('thinking_summary', {}))
- self.base_url = config_data.get(
- 'base_url', 'https://aqai.shudaodsj.com:22001')
- settings = Settings()
- def get_base_url() -> str:
- return settings.base_url
- def get_proxy_url(original_url: str) -> str:
- """将原始URL转换为代理URL(加密)"""
- if not original_url:
- return ""
- from .crypto import encrypt_url
- encrypted = encrypt_url(original_url)
- return f"{settings.base_url}/apiv1/oss/parse?url={encrypted}"
|