0064e946
tangwang
feat: 增量索引服务、租户配置...
|
1
2
3
|
"""
租户配置加载器。
|
038e4e2f
tangwang
refactor(i18n): t...
|
4
|
从统一配置文件(config.yaml)加载租户配置,包括主语言和索引语言(index_languages)。
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
5
6
7
|
"""
import logging
|
038e4e2f
tangwang
refactor(i18n): t...
|
8
|
from typing import Dict, Any, Optional, List
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
9
|
|
86d8358b
tangwang
config optimize
|
10
11
|
from config.loader import get_app_config
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
12
13
|
logger = logging.getLogger(__name__)
|
038e4e2f
tangwang
refactor(i18n): t...
|
14
|
# 支持的索引语言:code -> display name(供商家勾选主市场语言等场景使用)
|
6f7840cf
tangwang
refactor: rename ...
|
15
16
|
# 语言代码与展示名的双向映射(供翻译/LLM 提示等统一使用)
SOURCE_LANG_CODE_MAP: Dict[str, str] = {
|
038e4e2f
tangwang
refactor(i18n): t...
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
"en": "English",
"zh": "Chinese",
"zh_tw": "Traditional Chinese",
"ru": "Russian",
"ja": "Japanese",
"ko": "Korean",
"es": "Spanish",
"fr": "French",
"pt": "Portuguese",
"de": "German",
"it": "Italian",
"th": "Thai",
"vi": "Vietnamese",
"id": "Indonesian",
"ms": "Malay",
"ar": "Arabic",
"hi": "Hindi",
"he": "Hebrew",
"my": "Burmese",
"ta": "Tamil",
"ur": "Urdu",
"bn": "Bengali",
"pl": "Polish",
"nl": "Dutch",
"ro": "Romanian",
"tr": "Turkish",
"km": "Khmer",
"lo": "Lao",
"yue": "Cantonese",
"cs": "Czech",
"el": "Greek",
"sv": "Swedish",
"hu": "Hungarian",
"da": "Danish",
"fi": "Finnish",
"uk": "Ukrainian",
"bg": "Bulgarian",
}
|
6f7840cf
tangwang
refactor: rename ...
|
56
57
58
|
TARGET_LANG_CODE_MAP: Dict[str, str] = {v: k for k, v in SOURCE_LANG_CODE_MAP.items()}
|
038e4e2f
tangwang
refactor(i18n): t...
|
59
60
61
|
def normalize_index_languages(value: Any, primary_language: str = "en") -> List[str]:
"""
将 index_languages 配置规范化为合法语言代码列表。
|
26b910bd
tangwang
refactor service ...
|
62
|
仅做规范化,不做默认值兜底。
|
038e4e2f
tangwang
refactor(i18n): t...
|
63
|
"""
|
26b910bd
tangwang
refactor service ...
|
64
|
del primary_language
|
038e4e2f
tangwang
refactor(i18n): t...
|
65
|
if value is None:
|
26b910bd
tangwang
refactor service ...
|
66
|
return []
|
038e4e2f
tangwang
refactor(i18n): t...
|
67
|
if not isinstance(value, (list, tuple)):
|
26b910bd
tangwang
refactor service ...
|
68
|
return []
|
038e4e2f
tangwang
refactor(i18n): t...
|
69
70
71
72
73
74
|
valid: List[str] = []
seen: set = set()
for item in value:
code = (item or "").strip().lower()
if not code or code in seen:
continue
|
6f7840cf
tangwang
refactor: rename ...
|
75
|
if code in SOURCE_LANG_CODE_MAP:
|
038e4e2f
tangwang
refactor(i18n): t...
|
76
77
|
valid.append(code)
seen.add(code)
|
26b910bd
tangwang
refactor service ...
|
78
|
return valid
|
038e4e2f
tangwang
refactor(i18n): t...
|
79
80
|
|
26b910bd
tangwang
refactor service ...
|
81
82
83
84
|
def resolve_index_languages(
tenant_config: Dict[str, Any],
default_index_languages: List[str],
) -> List[str]:
|
038e4e2f
tangwang
refactor(i18n): t...
|
85
86
|
"""
从租户配置解析 index_languages。
|
86d8358b
tangwang
config optimize
|
87
|
若配置缺失或非法,则回退到默认配置。
|
038e4e2f
tangwang
refactor(i18n): t...
|
88
|
"""
|
86d8358b
tangwang
config optimize
|
89
90
91
92
93
|
normalized = normalize_index_languages(
tenant_config.get("index_languages"),
tenant_config.get("primary_language") or "en",
)
return normalized if normalized else list(default_index_languages)
|
038e4e2f
tangwang
refactor(i18n): t...
|
94
|
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
class TenantConfigLoader:
"""租户配置加载器。"""
def __init__(self):
"""初始化租户配置加载器。"""
self._config: Optional[Dict[str, Any]] = None
def load_config(self) -> Dict[str, Any]:
"""
加载租户配置(从统一配置文件)。
Returns:
租户配置字典,格式:{"tenants": {...}, "default": {...}}
"""
if self._config is not None:
return self._config
try:
|
86d8358b
tangwang
config optimize
|
114
115
|
tenant_cfg = get_app_config().tenants
default_cfg = tenant_cfg.default
|
26b910bd
tangwang
refactor service ...
|
116
117
118
119
120
121
122
123
124
125
126
127
|
if not isinstance(default_cfg, dict):
raise RuntimeError("tenant_config.default must be configured in config.yaml")
default_primary = (default_cfg.get("primary_language") or "en").strip().lower()
default_index_languages = normalize_index_languages(
default_cfg.get("index_languages"),
default_primary,
)
if not default_index_languages:
raise RuntimeError(
"tenant_config.default.index_languages must include at least one supported language"
)
|
86d8358b
tangwang
config optimize
|
128
|
tenants_cfg = tenant_cfg.tenants
|
26b910bd
tangwang
refactor service ...
|
129
130
131
132
133
134
135
136
137
138
139
|
if not isinstance(tenants_cfg, dict):
raise RuntimeError("tenant_config.tenants must be an object")
normalized_default = dict(default_cfg)
normalized_default["primary_language"] = default_primary
normalized_default["index_languages"] = default_index_languages
self._config = {
"default": normalized_default,
"tenants": tenants_cfg,
}
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
140
141
142
143
|
logger.info("Loaded tenant config from unified config.yaml")
return self._config
except Exception as e:
logger.error(f"Failed to load tenant config: {e}", exc_info=True)
|
26b910bd
tangwang
refactor service ...
|
144
|
raise
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
145
146
147
148
149
150
151
152
153
|
def get_tenant_config(self, tenant_id: str) -> Dict[str, Any]:
"""
获取指定租户的配置。
Args:
tenant_id: 租户ID
Returns:
|
038e4e2f
tangwang
refactor(i18n): t...
|
154
|
租户配置字典,若租户不存在则用默认配置。始终包含已解析的 index_languages。
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
155
156
157
|
"""
config = self.load_config()
tenant_id_str = str(tenant_id)
|
26b910bd
tangwang
refactor service ...
|
158
|
default = config["default"]
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
159
|
tenants = config.get("tenants", {})
|
26b910bd
tangwang
refactor service ...
|
160
161
162
|
raw = tenants[tenant_id_str] if tenant_id_str in tenants else {}
if raw and not isinstance(raw, dict):
raise RuntimeError(f"tenant_config.tenants.{tenant_id_str} must be an object")
|
038e4e2f
tangwang
refactor(i18n): t...
|
163
|
if tenant_id_str not in tenants:
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
164
|
logger.debug(f"Tenant {tenant_id} not found in config, using default")
|
26b910bd
tangwang
refactor service ...
|
165
166
167
168
169
170
171
|
merged = dict(default)
merged.update(raw)
out = dict(merged)
out["index_languages"] = resolve_index_languages(
merged,
default_index_languages=default["index_languages"],
)
|
038e4e2f
tangwang
refactor(i18n): t...
|
172
|
return out
|
0064e946
tangwang
feat: 增量索引服务、租户配置...
|
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
def reload(self):
"""重新加载配置(用于配置更新)。"""
self._config = None
return self.load_config()
# 全局实例
_tenant_config_loader: Optional[TenantConfigLoader] = None
def get_tenant_config_loader() -> TenantConfigLoader:
"""获取全局租户配置加载器实例。"""
global _tenant_config_loader
if _tenant_config_loader is None:
_tenant_config_loader = TenantConfigLoader()
return _tenant_config_loader
|