mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-07-28 00:31:14 +00:00
✨ Feature: 添加插件 Pydantic 相关使用方法 (#2563)
This commit is contained in:
@ -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` 格式](#配置项解析),例如:
|
||||
|
@ -79,9 +79,9 @@ except Exception as e:
|
||||
通常适配器需要一些配置项,例如平台连接密钥等。适配器的配置方法与[插件配置](../appendices/config#%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE)类似,例如:
|
||||
|
||||
```python title=config.py
|
||||
from pydantic import BaseModel, Extra
|
||||
from pydantic import BaseModel
|
||||
|
||||
class Config(BaseModel, extra=Extra.ignore):
|
||||
class Config(BaseModel):
|
||||
xxx_id: str
|
||||
xxx_token: str
|
||||
```
|
||||
|
@ -56,7 +56,7 @@ options:
|
||||
|
||||
## 创建配置文件
|
||||
|
||||
配置文件用于存放 NoneBot 运行所需要的配置项,使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`python-dotenv`](https://saurabh-kumar.com/python-dotenv/) 来读取配置。配置项需符合 dotenv 格式,复杂类型数据需使用 JSON 格式填写。具体可选配置方式以及配置项详情参考[配置](../appendices/config.mdx)。
|
||||
配置文件用于存放 NoneBot 运行所需要的配置项,使用 [`pydantic`](https://docs.pydantic.dev/) 以及 [`python-dotenv`](https://saurabh-kumar.com/python-dotenv/) 来读取配置。配置项需符合 dotenv 格式,复杂类型数据需使用 JSON 格式填写。具体可选配置方式以及配置项详情参考[配置](../appendices/config.mdx)。
|
||||
|
||||
在**项目文件夹**中创建一个 `.env` 文本文件,并写入以下内容:
|
||||
|
||||
|
@ -82,20 +82,19 @@ Message([MessageSegment.text("Hello, world!")])
|
||||
|
||||
#### 从字典数组构造
|
||||
|
||||
`Message` 对象支持 Pydantic 自定义类型构造,可以使用 Pydantic 的 `parse_obj_as` 方法进行构造。
|
||||
`Message` 对象支持 Pydantic 自定义类型构造,可以使用 Pydantic 的 `TypeAdapter` 方法进行构造。
|
||||
|
||||
```python
|
||||
from pydantic import parse_obj_as
|
||||
from pydantic import TypeAdapter
|
||||
from nonebot.adapters.console import Message, MessageSegment
|
||||
|
||||
# 由字典构造消息段
|
||||
parse_obj_as(
|
||||
MessageSegment, {"type": "text", "data": {"text": "text"}}
|
||||
TypeAdapter(MessageSegment).validate_python(
|
||||
{"type": "text", "data": {"text": "text"}}
|
||||
) == MessageSegment.text("text")
|
||||
|
||||
# 由字典数组构造消息序列
|
||||
parse_obj_as(
|
||||
Message,
|
||||
TypeAdapter(Message).validate_python(
|
||||
[MessageSegment.text("text"), {"type": "text", "data": {"text": "text"}}],
|
||||
) == Message([MessageSegment.text("text"), MessageSegment.text("text")])
|
||||
```
|
||||
|
Reference in New Issue
Block a user