- 形仪域 domains/xingyi:form_anchors(稳定辨识特征/年龄表现/许可禁忌/可变范围——生成内容不可静默覆盖锚点);forms(主仪/化仪/文字形仪,candidate→adopt 定相治理:未定相不进呈现位、主仪唯一、新主仪自动退役旧主仪);voice_profiles(三来源,授权克隆必填用途与传播范围,revoke-grant 撤回立即生效,assert-usable 合成前置校验拒绝撤回/过期) - ASR:元炁 SenseVoice /v1/audio/transcriptions 透传(Whisper 兼容 multipart);YUANQI_BASE_URL 未配置时 503 不降级不伪造——多模态关闭纪律 - 前端形仪工坊(人物详情页):真形锚点编辑(特征逐行解析)/候选登记定相废弃/声音档案建立与授权撤回;头像呈现位改走定相主仪(forms/primary);xingyi api 库 + mock + 组件 4 用例 - 退役:旧 avatar 模块(services/endpoints/avatar、avatar_dir 配置、avatar_url 字段、前端直传组件与测试) - 验收(test_m7_xingyi 三用例):未定相不成为正式形仪(含主仪唯一与旧主仪 retired 断言);克隆授权可撤回(缺用途拒/撤回即拒/过期同理/预设不受约束);关闭全部多模态后文字相伴完整可用(ASR 503 时镜树缘契百工照常——回归) - 四套件:后端 376、前端 203、BFF 4、神识 5 包全绿(2 个预存环境失败不变);迁移 008 净库+±1 干净
121 lines
4.0 KiB
Python
121 lines
4.0 KiB
Python
"""主 Settings:多继承所有子配置,统一以绝对路径 ``_env_file`` 加载 ``.env``。
|
|
|
|
子配置见同目录下的 ``app_config`` / ``auth_config`` / ``database_config`` / ``log_config`` /
|
|
``runtime_config`` / ``sandbox_config``。本文件聚合字段,并承载
|
|
跨子配置的路径解析与计算属性。
|
|
|
|
配置优先级(自高到低):命令行参数 > 系统环境变量 > ``.env`` > 类属性默认值。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from functools import cached_property
|
|
from pathlib import Path
|
|
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
from app.core.config.app_config import AppConfig
|
|
from app.core.config.auth_config import AuthConfig
|
|
from app.core.config.database_config import DatabaseConfig
|
|
from app.core.config.log_config import LogConfig
|
|
from app.core.config.runtime_config import RuntimeConfig
|
|
from app.core.config.sandbox_config import SandboxSettings
|
|
from app.core.config.time_config import TimeConfig
|
|
|
|
# backend 目录:app/core/config/settings.py → parents[3] = backend/
|
|
_BACKEND_DIR = Path(__file__).resolve().parents[3]
|
|
# .env 永远在项目根目录(backend 父级),以绝对路径定位
|
|
_ENV_FILE = _BACKEND_DIR.parent / ".env"
|
|
|
|
|
|
class Settings(
|
|
AppConfig,
|
|
AuthConfig,
|
|
DatabaseConfig,
|
|
LogConfig,
|
|
RuntimeConfig,
|
|
SandboxSettings,
|
|
TimeConfig,
|
|
BaseSettings,
|
|
):
|
|
"""应用配置类。
|
|
|
|
所有配置项可通过 ``.env`` 文件或环境变量覆盖。路径配置会自动解析为绝对路径。
|
|
"""
|
|
|
|
model_config = SettingsConfigDict(
|
|
env_file=str(_ENV_FILE), # 绝对路径,不使用 python-dotenv
|
|
env_file_encoding="utf-8",
|
|
case_sensitive=False, # 环境变量名不区分大小写
|
|
extra="ignore", # 忽略未定义的额外字段
|
|
)
|
|
|
|
# ==================== 路径解析 ====================
|
|
|
|
@cached_property
|
|
def backend_dir(self) -> Path:
|
|
"""backend 目录路径。"""
|
|
return _BACKEND_DIR
|
|
|
|
@cached_property
|
|
def project_root(self) -> Path:
|
|
"""项目根目录路径(backend 的父级)。"""
|
|
return _BACKEND_DIR.parent
|
|
|
|
def resolve_from_backend(self, value: str) -> Path:
|
|
"""解析相对于 backend 目录的路径为绝对路径。
|
|
|
|
Args:
|
|
value: 相对路径或绝对路径字符串
|
|
|
|
Returns:
|
|
解析后的绝对路径
|
|
"""
|
|
path = Path(value)
|
|
if path.is_absolute():
|
|
return path
|
|
return (self.backend_dir / path).resolve()
|
|
|
|
# ==================== 计算属性 ====================
|
|
|
|
@property
|
|
def resolved_database_url(self) -> str:
|
|
"""解析数据库连接 URL。
|
|
|
|
如果设置了 ``database_url`` 则直接使用,否则根据 ``database_type`` 构建。
|
|
"""
|
|
if self.database_url:
|
|
return self.database_url
|
|
if self.database_type == "sqlite":
|
|
db_path = self.resolve_from_backend(self.sqlite_database_path)
|
|
return f"sqlite+aiosqlite:///{db_path}"
|
|
password = self.postgres_password
|
|
ssl = "?ssl=require" if self.postgres_ssl else ""
|
|
return (
|
|
f"postgresql+asyncpg://{self.postgres_user}:{password}"
|
|
f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}{ssl}"
|
|
)
|
|
|
|
@cached_property
|
|
def resolved_log_dir(self) -> Path:
|
|
"""解析日志目录为绝对路径。"""
|
|
return self.resolve_from_backend(self.log_dir)
|
|
|
|
@cached_property
|
|
def resolved_character_templates_path(self) -> Path:
|
|
"""解析人物模板配置文件路径。
|
|
|
|
如果配置文件不存在,尝试使用示例配置文件。
|
|
"""
|
|
configured = self.resolve_from_backend(self.character_templates_path)
|
|
if configured.exists():
|
|
return configured
|
|
example = self.project_root / "config" / "character_templates.example.yaml"
|
|
if example.exists():
|
|
return example
|
|
return configured
|
|
|
|
|
|
# 全局配置实例
|
|
settings = Settings()
|