Skip to content

Commit 8821218

Browse files
authored
🔀 Merge pull request #202
Pre Release 2.0.0a10
2 parents 9a34647 + 27b9b41 commit 8821218

File tree

25 files changed

+856
-169
lines changed

25 files changed

+856
-169
lines changed

.github/workflows/build_docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Build API Doc
22

33
on:
44
pull_request:
5-
types: [ opened, synchronize, reopened ]
5+
types: [opened, synchronize, reopened]
66

77
jobs:
88
build:
@@ -30,7 +30,7 @@ jobs:
3030
3131
- name: Set up dependencies
3232
run: |
33-
poetry install
33+
poetry install -E all
3434
3535
- name: Build Doc
3636
run: poetry run sphinx-build -M markdown ./docs_build ./build

docs/.vuepress/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ module.exports = context => ({
198198
title: "nonebot.drivers.fastapi 模块",
199199
path: "drivers/fastapi"
200200
},
201+
{
202+
title: "nonebot.drivers.quart 模块",
203+
path: "drivers/quart"
204+
},
201205
{
202206
title: "nonebot.adapters 模块",
203207
path: "adapters/"
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,117 @@
11
# 跨插件访问
2+
3+
由于 `nonebot2` 独特的插件加载机制,在使用 python 原有的 import 机制来进行插件之间的访问时,很可能会有奇怪的或者意料以外的情况发生。为了避免这种情况的发生,您可以有两种方法来实现跨插件访问:
4+
5+
1. 将插件间的要使用的公共代码剥离出来,作为公共文件或者文件夹,提供给插件加以调用。
6+
2. 使用 `nonebot2` 提供的 `export``require` 机制,来实现插件间的互相调用。
7+
8+
第一种方法比较容易理解和实现,这里不再赘述,但需要注意的是,请不要将公共文件或者公共文件夹作为**插件**`nonebot2` 加载。
9+
10+
下面将介绍第二种方法—— `export``require` 机制:
11+
12+
## 使用 export and require
13+
14+
现在,假定有两个插件 `pluginA``pluginB`,需要在 `pluginB` 中调用 `pluginA` 中的一个变量 `varA` 和一个函数 `funcA`
15+
16+
在上面的条件中涉及到了两种操作:一种是在 `pluginA``导出对象` 操作;而另一种是在 `pluginB``导入对象` 操作。在 `nonebot2` 中,`导出对象` 的操作用 `export` 机制来实现,`导入对象` 的操作用 `require` 机制来实现。下面,我们将逐一进行介绍。
17+
18+
:::warning 警告
19+
20+
使用这个方法进行跨插件访问时,**需要先加载`导出对象`的插件,再加载`导入对象`的插件。**
21+
22+
:::
23+
24+
### 使用 export
25+
26+
`pluginA` 中,我们调用 `export` 机制 `导出对象`
27+
28+
`export` 机制调用前,我们需要保证导出的对象已经被定义,比如:
29+
30+
```python
31+
varA = "varA"
32+
33+
34+
def funcA():
35+
return "funcA"
36+
```
37+
38+
在确保定义之后,我们可以从 `nonebot.plugin` 导入 `export()` 方法, `export()` 方法会返回一个特殊的字典 `export`
39+
40+
```python
41+
from nonebot.plugin import export
42+
43+
export=export()
44+
```
45+
46+
这个字典可以用来装载导出的对象,它的 key 是对象导出后的命名,value 是对象本身,我们可以直接创建新的 `key` - `value` 对导出对象:
47+
48+
```python
49+
export.vA = varA
50+
export.fA = funcA
51+
```
52+
53+
除此之外,也支持 `嵌套` 导出对象:
54+
55+
```python
56+
export.sub.vA = varA
57+
export.sub.fA = funcA
58+
```
59+
60+
特别地,对于 `函数对象` 而言,`export` 支持用 `装饰器` 的方法来导出,因此,我们可以这样定义 `funcA`
61+
62+
```python
63+
@export.sub
64+
def funcA():
65+
return "funcA"
66+
```
67+
68+
或者:
69+
70+
```python
71+
@export
72+
def funcA():
73+
return "funcA"
74+
```
75+
76+
通过 `装饰器` 的方法导出函数时,命名固定为函数的命名,也就是说,上面的两个例子等同于:
77+
78+
```python
79+
export.sub.funcA = funcA
80+
81+
export.funcA = funcA
82+
```
83+
84+
这样,我们就成功导出 `varA``funcA` 对象了。
85+
86+
下面我们将介绍如何在 `pluginB` 中导入这些对象。
87+
88+
### 使用 require
89+
90+
`pluginB` 中,我们调用 `require` 机制 `导入对象`
91+
92+
:::warning 警告
93+
94+
在导入来自其他插件的对象时, 请确保导出该对象的插件在引用该对象的插件之前加载。如果该插件并未被加载,则会尝试加载,加载失败则会返回 `None`
95+
96+
:::
97+
98+
我们可以从 `nonebot.plugin` 中导入 `require()` 方法:
99+
100+
```python
101+
from nonebot.plugin import require
102+
```
103+
104+
`require()` 方法的参数是插件名, 它会返回在指定插件中,用 `export()` 方法创建的字典。
105+
106+
```python
107+
require_A = require('pluginA')
108+
```
109+
110+
在之前,这个字典已经存入了 `'vA'` - `varA`, `'fA'` - `funcA``'funcA'` - `funcA` 这样的 `key` - `value` 对。因此在这里我们直接用 `属性` 的方法来获取导入对象:
111+
112+
```python
113+
varA = require_A.vA
114+
funcA = require_A.fA or require_A.funcA
115+
```
116+
117+
这样,我们就在 `pluginB` 中成功导入了 `varA``funcA` 对象了。

docs/api/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
* [nonebot.drivers.fastapi](drivers/fastapi.html)
4444

4545

46+
* [nonebot.drivers.quart](drivers/quart.html)
47+
48+
4649
* [nonebot.adapters](adapters/)
4750

4851

docs/api/adapters/mirai.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -965,15 +965,40 @@ CQHTTP 协议 MessageSegment 适配。具体方法参考 [mirai-api-http 消息
965965

966966
基类:[`nonebot.adapters.Message`](README.md#nonebot.adapters.Message)
967967

968-
Mirai 协议 Messaqge 适配
968+
Mirai 协议 Message 适配
969969

970970
由于Mirai协议的Message实现较为特殊, 故使用MessageChain命名
971971

972972

973+
### `reduce()`
974+
975+
976+
* **说明**
977+
978+
忽略为空的消息段, 合并相邻的纯文本消息段
979+
980+
981+
973982
### `export()`
974983

975984
导出为可以被正常json序列化的数组
976985

986+
987+
### `extract_first(*type)`
988+
989+
990+
* **说明**
991+
992+
弹出该消息链的第一个消息
993+
994+
995+
996+
* **参数**
997+
998+
999+
* \*type: MessageType: 指定的消息类型, 当指定后如类型不匹配不弹出
1000+
1001+
9771002
# NoneBot.adapters.mirai.utils 模块
9781003

9791004

@@ -1070,20 +1095,6 @@ mirai-api-http 协议事件,字段与 mirai-api-http 一致。各事件字段
10701095
> * `MEMBER`: 普通群成员
10711096
10721097

1073-
## _class_ `MessageChain`
1074-
1075-
基类:[`nonebot.adapters.Message`](README.md#nonebot.adapters.Message)
1076-
1077-
Mirai 协议 Messaqge 适配
1078-
1079-
由于Mirai协议的Message实现较为特殊, 故使用MessageChain命名
1080-
1081-
1082-
### `export()`
1083-
1084-
导出为可以被正常json序列化的数组
1085-
1086-
10871098
## _class_ `MessageEvent`
10881099

10891100
基类:`nonebot.adapters.mirai.event.base.Event`

docs/api/drivers/quart.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
contentSidebar: true
3+
sidebarDepth: 0
4+
---
5+
6+
# NoneBot.drivers.quart 模块
7+
8+
## Quart 驱动适配
9+
10+
后端使用方法请参考: [Quart 文档](https://pgjones.gitlab.io/quart/index.html)
11+
12+
13+
## _class_ `Driver`
14+
15+
基类:[`nonebot.drivers.Driver`](README.md#nonebot.drivers.Driver)
16+
17+
Quart 驱动框架
18+
19+
20+
* **上报地址**
21+
22+
23+
* `/{adapter name}/http`: HTTP POST 上报
24+
25+
26+
* `/{adapter name}/ws`: WebSocket 上报
27+
28+
29+
30+
### _property_ `type`
31+
32+
驱动名称: `quart`
33+
34+
35+
### _property_ `server_app`
36+
37+
`Quart` 对象
38+
39+
40+
### _property_ `asgi`
41+
42+
`Quart` 对象
43+
44+
45+
### _property_ `logger`
46+
47+
fastapi 使用的 logger
48+
49+
50+
### `on_startup(func)`
51+
52+
参考文档: [Startup and Shutdown](https://pgjones.gitlab.io/quart/how_to_guides/startup_shutdown.html)
53+
54+
55+
### `on_shutdown(func)`
56+
57+
参考文档: [Startup and Shutdown](https://pgjones.gitlab.io/quart/how_to_guides/startup_shutdown.html)
58+
59+
60+
### `run(host=None, port=None, *, app=None, **kwargs)`
61+
62+
使用 `uvicorn` 启动 Quart

docs/guide/creating-a-matcher.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ async def async_checker(bot: Bot, event: Event, state: T_State) -> bool:
123123
def sync_checker(bot: Bot, event: Event, state: T_State) -> bool:
124124
return True
125125

126-
def check(arg1, args2):
126+
def check(arg1, arg2):
127127

128128
async def _checker(bot: Bot, event: Event, state: T_State) -> bool:
129129
return bool(arg1 + arg2)

docs/guide/loading-a-plugin.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@
66

77
`bot.py` 文件中添加以下行:
88

9-
```python{5}
9+
```python{8}
1010
import nonebot
11+
from nonebot.adapters.cqhttp import Bot
1112
1213
nonebot.init()
13-
# 加载 nonebot 内置插件
14-
nonebot.load_builtin_plugins()
14+
15+
driver = nonebot.get_driver()
16+
driver.register_adapter("cqhttp", Bot) # 注册 CQHTTP 的 Adapter
17+
nonebot.load_builtin_plugins() # 加载 nonebot 内置插件
1518
1619
app = nonebot.get_asgi()
1720
1821
if __name__ == "__main__":
1922
nonebot.run()
2023
```
2124

25+
::: warning
26+
目前, 内建插件仅支持 CQHTTP 的 Adapter
27+
28+
如果您使用的是其他 Adapter, 请移步该 Adapter 相应的文档
29+
:::
30+
2231
这将会加载 nonebot 内置的插件,它包含:
2332

2433
- 命令 `say`:可由**superuser**使用,可以将消息内容由特殊纯文本转为富文本

docs/guide/mirai-guide.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,36 @@ Mirai-API-HTTP 的适配器以 [AGPLv3 许可](https://opensource.org/licenses/A
193193
```
194194
195195
恭喜你, 你的配置已经成功!
196+
197+
现在, 我们可以写一个简单的插件来测试一下
198+
199+
```python
200+
from nonebot.plugin import on_keyword, on_command
201+
from nonebot.rule import to_me
202+
from nonebot.adapters.mirai import Bot, MessageEvent
203+
204+
message_test = on_keyword({'reply'}, rule=to_me())
205+
206+
207+
@message_test.handle()
208+
async def _message(bot: Bot, event: MessageEvent):
209+
text = event.get_plaintext()
210+
await bot.send(event, text, at_sender=True)
211+
212+
213+
command_test = on_command('miecho')
214+
215+
216+
@command_test.handle()
217+
async def _echo(bot: Bot, event: MessageEvent):
218+
text = event.get_plaintext()
219+
await bot.send(event, text, at_sender=True)
220+
```
221+
222+
它具有两种行为
223+
224+
- 在指定机器人,即私聊、群聊内@机器人、群聊内称呼机器人昵称的情况下 (即 [Rule: to_me](../api/rule.md#to-me)), 如果消息内包含 `reply` 字段, 则该消息会被机器人重复一次
225+
226+
- 在执行指令`miecho xxx`时, 机器人会发送回参数`xxx`
227+
228+
至此, 你已经初步掌握了如何使用 Mirai Adapter

docs_build/README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ NoneBot Api Reference
1515
- `nonebot.exception <exception.html>`_
1616
- `nonebot.drivers <drivers/>`_
1717
- `nonebot.drivers.fastapi <drivers/fastapi.html>`_
18+
- `nonebot.drivers.quart <drivers/quart.html>`_
1819
- `nonebot.adapters <adapters/>`_
1920
- `nonebot.adapters.cqhttp <adapters/cqhttp.html>`_
2021
- `nonebot.adapters.ding <adapters/ding.html>`_

0 commit comments

Comments
 (0)