Feature: 添加插件 Pydantic 相关使用方法 (#2563)

This commit is contained in:
Ju4tCode
2024-02-05 14:00:49 +08:00
committed by GitHub
parent 2ebf956599
commit dace63d9d2
10 changed files with 93 additions and 19 deletions

View File

@ -19,6 +19,25 @@ NoneBot 使用 [`pydantic`](https://docs.pydantic.dev/) 以及 [`python-dotenv`]
NoneBot 内置的配置项列表及含义可以在[内置配置项](#内置配置项)中查看。
:::caution 注意
NoneBot 自 2.2.0 起兼容了 Pydantic v1 与 v2 版本,以下文档中 Pydantic 相关示例均采用 v2 版本用法。
如果在使用商店或其他第三方插件的过程中遇到 Pydantic 相关警告或报错,例如:
```python
pydantic_core._pydantic_core.ValidationError: 1 validation error for Config
Input should be a valid dictionary or instance of Config [type=model_type, input_value=Config(...), input_type=Config]
```
请考虑降级 Pydantic 至 v1 版本:
```bash
pip install --force-reinstall 'pydantic~=1.10'
```
:::
## 配置项的加载
在 NoneBot 中,我们可以把配置途径分为 **直接传入**、**系统环境变量**、**dotenv 配置文件** 三种,其加载优先级依次由高到低。
@ -182,18 +201,19 @@ superusers = config.superusers
在 NoneBot 中,我们使用强大高效的 `pydantic` 来定义配置模型,这个模型可以被用于配置的读取和类型检查等。例如在 `weather` 插件目录中新建 `config.py` 来定义一个模型:
```python title=weather/config.py
from pydantic import BaseModel, validator
from pydantic import BaseModel, field_validator
class Config(BaseModel):
weather_api_key: str
weather_command_priority: int = 10
weather_plugin_enabled: bool = True
@validator("weather_command_priority")
def check_priority(cls, v):
if isinstance(v, int) and v >= 1:
@field_validator("weather_command_priority")
@classmethod
def check_priority(cls, v: int) -> int:
if v >= 1:
return v
raise ValueError("weather command priority must be an integer and greater than 1")
raise ValueError("weather command priority must greater than 1")
```
在 `config.py` 中,我们定义了一个 `Config` 类,它继承自 `pydantic.BaseModel`,并定义了一些配置项。在 `Config` 类中,我们还定义了一个 `check_priority` 方法,它用于检查 `weather_command_priority` 配置项的合法性。更多关于 `pydantic` 的编写方式,可以参考 [pydantic 官方文档](https://docs.pydantic.dev/)。
@ -201,11 +221,11 @@ class Config(BaseModel):
在定义好配置模型后,我们可以在插件加载时获取全局配置,导入插件自身的配置模型并使用:
```python {5,11} title=weather/__init__.py
from nonebot import get_driver
from nonebot import get_plugin_config
from .config import Config
plugin_config = Config.parse_obj(get_driver().config)
plugin_config = get_plugin_config(Config)
weather = on_command(
"天气",
@ -239,11 +259,11 @@ class Config(BaseModel):
```
```python title=weather/__init__.py
from nonebot import get_driver
from nonebot import get_plugin_config
from .config import Config
plugin_config = Config.parse_obj(get_driver().config).weather
plugin_config = get_plugin_config(Config).weather
```
这样我们就可以省略插件配置项名称中的前缀 `weather_` 了。但需要注意的是,如果我们使用了 scope 配置,那么在配置文件中也需要使用 [`env_nested_delimiter` 格式](#配置项解析),例如: