Allow to add config in plugin toml (#1033)

This commit is contained in:
Wu Clan
2026-01-23 16:42:24 +08:00
committed by GitHub
parent f2b246089d
commit ced2b8d269
2 changed files with 54 additions and 2 deletions

View File

@@ -5,9 +5,10 @@ from re import Pattern
from typing import Any, Literal
from pydantic import model_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic_settings import BaseSettings, PydanticBaseSettingsSource, SettingsConfigDict
from backend.core.path_conf import ENV_EXAMPLE_FILE_PATH, ENV_FILE_PATH
from backend.plugin.settings_source import PluginSettingsSource
class Settings(BaseSettings):
@@ -16,10 +17,22 @@ class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=ENV_FILE_PATH,
env_file_encoding='utf-8',
extra='ignore',
extra='allow',
case_sensitive=True,
)
@classmethod
def settings_customise_sources(
cls,
settings_cls: type[BaseSettings],
init_settings: PydanticBaseSettingsSource,
env_settings: PydanticBaseSettingsSource,
dotenv_settings: PydanticBaseSettingsSource,
file_secret_settings: PydanticBaseSettingsSource,
) -> tuple[PydanticBaseSettingsSource, ...]:
"""自定义配置源优先级"""
return env_settings, dotenv_settings, PluginSettingsSource(settings_cls)
# .env 当前环境
ENVIRONMENT: Literal['dev', 'prod']

View File

@@ -0,0 +1,39 @@
import os
from typing import Any
import rtoml
from pydantic.fields import FieldInfo
from pydantic_settings import PydanticBaseSettingsSource
from backend.core.path_conf import PLUGIN_DIR
class PluginSettingsSource(PydanticBaseSettingsSource):
"""从所有插件的 plugin.toml 加载配置的自定义配置源"""
def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, bool]:
"""获取单个字段的值"""
# 不在这里实现,使用 __call__ 批量加载
return None, field_name, False
def __call__(self) -> dict[str, Any]:
"""加载所有插件配置"""
merged_settings: dict[str, Any] = {}
for item in os.listdir(PLUGIN_DIR):
item_path = PLUGIN_DIR / item
if not os.path.isdir(item_path):
continue
if '__init__.py' not in os.listdir(item_path):
continue
toml_path = item_path / 'plugin.toml'
if toml_path.exists():
with open(toml_path, encoding='utf-8') as f:
config = rtoml.load(f)
plugin_settings = config.get('settings', {})
merged_settings.update(plugin_settings)
return merged_settings