mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-27 18:45:05 +08:00
💡 add docstrings
This commit is contained in:
parent
f9674da6ea
commit
c4e204001e
@ -1,6 +1,10 @@
|
|||||||
"""本模块定义了协议适配基类,各协议请继承以下基类。
|
"""本模块定义了协议适配基类,各协议请继承以下基类。
|
||||||
|
|
||||||
使用 {ref}`nonebot.drivers.Driver.register_adapter` 注册适配器
|
使用 {ref}`nonebot.drivers.Driver.register_adapter` 注册适配器。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 0
|
||||||
|
description: nonebot.adapters 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 1
|
||||||
|
description: nonebot.adapters._adapter 模块
|
||||||
|
"""
|
||||||
import abc
|
import abc
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import Any, Dict, AsyncGenerator
|
from typing import Any, Dict, AsyncGenerator
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 2
|
||||||
|
description: nonebot.adapters._bot 模块
|
||||||
|
"""
|
||||||
import abc
|
import abc
|
||||||
import asyncio
|
import asyncio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 3
|
||||||
|
description: nonebot.adapters._event 模块
|
||||||
|
"""
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 4
|
||||||
|
description: nonebot.adapters._message 模块
|
||||||
|
"""
|
||||||
import abc
|
import abc
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from dataclasses import field, asdict, dataclass
|
from dataclasses import field, asdict, dataclass
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 5
|
||||||
|
description: nonebot.adapters._template 模块
|
||||||
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
import functools
|
import functools
|
||||||
from string import Formatter
|
from string import Formatter
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
"""本模块模块实现了依赖注入的定义与处理。"""
|
"""本模块模块实现了依赖注入的定义与处理。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 0
|
||||||
|
description: nonebot.dependencies 模块
|
||||||
|
"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 1
|
||||||
|
description: nonebot.dependencies.utils 模块
|
||||||
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Dict, Callable
|
from typing import Any, Dict, Callable
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
"""
|
"""本模块定义了驱动适配器基类。
|
||||||
## 后端驱动适配基类
|
|
||||||
|
|
||||||
各驱动请继承以下基类
|
各驱动请继承以下基类。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 0
|
||||||
|
description: nonebot.drivers 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
@ -35,57 +38,38 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class Driver(abc.ABC):
|
class Driver(abc.ABC):
|
||||||
"""
|
"""Driver 基类。
|
||||||
Driver 基类。
|
|
||||||
|
参数:
|
||||||
|
env: 包含环境信息的 Env 对象
|
||||||
|
config: 包含配置信息的 Config 对象
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_adapters: Dict[str, "Adapter"] = {}
|
_adapters: Dict[str, "Adapter"] = {}
|
||||||
"""
|
"""已注册的适配器列表"""
|
||||||
已注册的适配器列表
|
|
||||||
"""
|
|
||||||
_bot_connection_hook: Set[T_BotConnectionHook] = set()
|
_bot_connection_hook: Set[T_BotConnectionHook] = set()
|
||||||
"""
|
"""Bot 连接建立时执行的函数"""
|
||||||
Bot 连接建立时执行的函数
|
|
||||||
"""
|
|
||||||
_bot_disconnection_hook: Set[T_BotDisconnectionHook] = set()
|
_bot_disconnection_hook: Set[T_BotDisconnectionHook] = set()
|
||||||
"""
|
"""Bot 连接断开时执行的函数"""
|
||||||
Bot 连接断开时执行的函数
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, env: Env, config: Config):
|
def __init__(self, env: Env, config: Config):
|
||||||
"""
|
|
||||||
参数:
|
|
||||||
env: 包含环境信息的 Env 对象
|
|
||||||
config: 包含配置信息的 Config 对象
|
|
||||||
"""
|
|
||||||
self.env: str = env.environment
|
self.env: str = env.environment
|
||||||
"""
|
"""环境名称"""
|
||||||
环境名称
|
|
||||||
"""
|
|
||||||
self.config: Config = config
|
self.config: Config = config
|
||||||
"""
|
"""全局配置对象"""
|
||||||
配置对象
|
|
||||||
"""
|
|
||||||
self._clients: Dict[str, "Bot"] = {}
|
self._clients: Dict[str, "Bot"] = {}
|
||||||
"""
|
|
||||||
已连接的 Bot
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bots(self) -> Dict[str, "Bot"]:
|
def bots(self) -> Dict[str, "Bot"]:
|
||||||
"""
|
"""获取当前所有已连接的 Bot"""
|
||||||
获取当前所有已连接的 Bot
|
|
||||||
"""
|
|
||||||
return self._clients
|
return self._clients
|
||||||
|
|
||||||
def register_adapter(self, adapter: Type["Adapter"], **kwargs) -> None:
|
def register_adapter(self, adapter: Type["Adapter"], **kwargs) -> None:
|
||||||
"""
|
"""注册一个协议适配器
|
||||||
注册一个协议适配器
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
name: 适配器名称,用于在连接时进行识别
|
adapter: 适配器类
|
||||||
adapter: 适配器 Class
|
kwargs: 其他传递给适配器的参数
|
||||||
**kwargs: 其他传递给适配器的参数
|
|
||||||
"""
|
"""
|
||||||
name = adapter.get_name()
|
name = adapter.get_name()
|
||||||
if name in self._adapters:
|
if name in self._adapters:
|
||||||
@ -121,36 +105,36 @@ class Driver(abc.ABC):
|
|||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def on_startup(self, func: Callable) -> Callable:
|
def on_startup(self, func: Callable) -> Callable:
|
||||||
"""注册一个在驱动启动时运行的函数"""
|
"""注册一个在驱动器启动时执行的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def on_shutdown(self, func: Callable) -> Callable:
|
def on_shutdown(self, func: Callable) -> Callable:
|
||||||
"""注册一个在驱动停止时运行的函数"""
|
"""注册一个在驱动器停止时执行的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def on_bot_connect(self, func: T_BotConnectionHook) -> T_BotConnectionHook:
|
def on_bot_connect(self, func: T_BotConnectionHook) -> T_BotConnectionHook:
|
||||||
"""
|
"""装饰一个函数使他在 bot 连接成功时执行。
|
||||||
装饰一个函数使他在 bot 通过 WebSocket 连接成功时执行。
|
|
||||||
|
|
||||||
参数:
|
插槽函数参数:
|
||||||
bot: 当前连接上的 Bot 对象
|
|
||||||
|
- bot: 当前连接上的 Bot 对象
|
||||||
"""
|
"""
|
||||||
self._bot_connection_hook.add(func)
|
self._bot_connection_hook.add(func)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def on_bot_disconnect(self, func: T_BotDisconnectionHook) -> T_BotDisconnectionHook:
|
def on_bot_disconnect(self, func: T_BotDisconnectionHook) -> T_BotDisconnectionHook:
|
||||||
"""
|
"""装饰一个函数使他在 bot 连接断开时执行。
|
||||||
装饰一个函数使他在 bot 通过 WebSocket 连接断开时执行。
|
|
||||||
|
|
||||||
参数:
|
插槽函数参数:
|
||||||
bot: 当前连接上的 Bot 对象
|
|
||||||
|
- bot: 当前连接上的 Bot 对象
|
||||||
"""
|
"""
|
||||||
self._bot_disconnection_hook.add(func)
|
self._bot_disconnection_hook.add(func)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def _bot_connect(self, bot: "Bot") -> None:
|
def _bot_connect(self, bot: "Bot") -> None:
|
||||||
"""在 WebSocket 连接成功后,调用该函数来注册 bot 对象"""
|
"""在连接成功后,调用该函数来注册 bot 对象"""
|
||||||
if bot.self_id in self._clients:
|
if bot.self_id in self._clients:
|
||||||
raise RuntimeError(f"Duplicate bot connection with id {bot.self_id}")
|
raise RuntimeError(f"Duplicate bot connection with id {bot.self_id}")
|
||||||
self._clients[bot.self_id] = bot
|
self._clients[bot.self_id] = bot
|
||||||
@ -169,7 +153,7 @@ class Driver(abc.ABC):
|
|||||||
asyncio.create_task(_run_hook(bot))
|
asyncio.create_task(_run_hook(bot))
|
||||||
|
|
||||||
def _bot_disconnect(self, bot: "Bot") -> None:
|
def _bot_disconnect(self, bot: "Bot") -> None:
|
||||||
"""在 WebSocket 连接断开后,调用该函数来注销 bot 对象"""
|
"""在连接断开后,调用该函数来注销 bot 对象"""
|
||||||
if bot.self_id in self._clients:
|
if bot.self_id in self._clients:
|
||||||
del self._clients[bot.self_id]
|
del self._clients[bot.self_id]
|
||||||
|
|
||||||
@ -188,32 +172,33 @@ class Driver(abc.ABC):
|
|||||||
|
|
||||||
|
|
||||||
class ForwardMixin(abc.ABC):
|
class ForwardMixin(abc.ABC):
|
||||||
|
"""客户端混入基类。"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""客户端驱动类型名称"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def request(self, setup: Request) -> Response:
|
async def request(self, setup: Request) -> Response:
|
||||||
|
"""发送一个 HTTP 请求"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def websocket(self, setup: Request) -> AsyncGenerator[WebSocket, None]:
|
async def websocket(self, setup: Request) -> AsyncGenerator[WebSocket, None]:
|
||||||
|
"""发起一个 WebSocket 连接"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
yield # used for static type checking's generator detection
|
yield # used for static type checking's generator detection
|
||||||
|
|
||||||
|
|
||||||
class ForwardDriver(Driver, ForwardMixin):
|
class ForwardDriver(Driver, ForwardMixin):
|
||||||
"""
|
"""客户端基类。将客户端框架封装,以满足适配器使用。"""
|
||||||
Forward Driver 基类。将客户端框架封装,以满足适配器使用。
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ReverseDriver(Driver):
|
class ReverseDriver(Driver):
|
||||||
"""
|
"""服务端基类。将后端框架封装,以满足适配器使用。"""
|
||||||
Reverse Driver 基类。将后端框架封装,以满足适配器使用。
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
@ -229,20 +214,26 @@ class ReverseDriver(Driver):
|
|||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def setup_http_server(self, setup: "HTTPServerSetup") -> None:
|
def setup_http_server(self, setup: "HTTPServerSetup") -> None:
|
||||||
|
"""设置一个 HTTP 服务器路由配置"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def setup_websocket_server(self, setup: "WebSocketServerSetup") -> None:
|
def setup_websocket_server(self, setup: "WebSocketServerSetup") -> None:
|
||||||
|
"""设置一个 WebSocket 服务器路由配置"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Driver]:
|
def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Driver]:
|
||||||
|
"""将一个驱动器和多个混入类合并。"""
|
||||||
# check first
|
# check first
|
||||||
assert issubclass(driver, Driver), "`driver` must be subclass of Driver"
|
assert issubclass(driver, Driver), "`driver` must be subclass of Driver"
|
||||||
assert all(
|
assert all(
|
||||||
map(lambda m: issubclass(m, ForwardMixin), mixins)
|
map(lambda m: issubclass(m, ForwardMixin), mixins)
|
||||||
), "`mixins` must be subclass of ForwardMixin"
|
), "`mixins` must be subclass of ForwardMixin"
|
||||||
|
|
||||||
|
if not mixins:
|
||||||
|
return driver
|
||||||
|
|
||||||
class CombinedDriver(*mixins, driver, ForwardDriver): # type: ignore
|
class CombinedDriver(*mixins, driver, ForwardDriver): # type: ignore
|
||||||
@property
|
@property
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
@ -257,6 +248,8 @@ def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Dr
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class HTTPServerSetup:
|
class HTTPServerSetup:
|
||||||
|
"""HTTP 服务器路由配置。"""
|
||||||
|
|
||||||
path: URL # path should not be absolute, check it by URL.is_absolute() == False
|
path: URL # path should not be absolute, check it by URL.is_absolute() == False
|
||||||
method: str
|
method: str
|
||||||
name: str
|
name: str
|
||||||
@ -265,6 +258,8 @@ class HTTPServerSetup:
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class WebSocketServerSetup:
|
class WebSocketServerSetup:
|
||||||
|
"""WebSocket 服务器路由配置。"""
|
||||||
|
|
||||||
path: URL # path should not be absolute, check it by URL.is_absolute() == False
|
path: URL # path should not be absolute, check it by URL.is_absolute() == False
|
||||||
name: str
|
name: str
|
||||||
handle_func: Callable[[WebSocket], Awaitable[Any]]
|
handle_func: Callable[[WebSocket], Awaitable[Any]]
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
"""
|
"""[AIOHTTP](https://aiohttp.readthedocs.io/en/stable/) 驱动适配器。
|
||||||
## AIOHTTP 驱动适配
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nb driver install aiohttp
|
||||||
|
# 或者
|
||||||
|
pip install nonebot2[aiohttp]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
本驱动仅支持客户端连接
|
本驱动仅支持客户端连接
|
||||||
|
:::
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 2
|
||||||
|
description: nonebot.drivers.aiohttp 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import AsyncGenerator
|
from typing import Type, AsyncGenerator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from nonebot.typing import overrides
|
from nonebot.typing import overrides
|
||||||
@ -12,7 +23,12 @@ from nonebot.drivers import Request, Response
|
|||||||
from nonebot.exception import WebSocketClosed
|
from nonebot.exception import WebSocketClosed
|
||||||
from nonebot.drivers._block_driver import BlockDriver
|
from nonebot.drivers._block_driver import BlockDriver
|
||||||
from nonebot.drivers import WebSocket as BaseWebSocket
|
from nonebot.drivers import WebSocket as BaseWebSocket
|
||||||
from nonebot.drivers import HTTPVersion, ForwardMixin, combine_driver
|
from nonebot.drivers import (
|
||||||
|
HTTPVersion,
|
||||||
|
ForwardMixin,
|
||||||
|
ForwardDriver,
|
||||||
|
combine_driver,
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import aiohttp
|
import aiohttp
|
||||||
@ -23,6 +39,8 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
class Mixin(ForwardMixin):
|
class Mixin(ForwardMixin):
|
||||||
|
"""AIOHTTP Mixin"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(ForwardMixin)
|
@overrides(ForwardMixin)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
@ -84,6 +102,8 @@ class Mixin(ForwardMixin):
|
|||||||
|
|
||||||
|
|
||||||
class WebSocket(BaseWebSocket):
|
class WebSocket(BaseWebSocket):
|
||||||
|
"""AIOHTTP Websocket Wrapper"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -138,4 +158,5 @@ class WebSocket(BaseWebSocket):
|
|||||||
await self.websocket.send_bytes(data)
|
await self.websocket.send_bytes(data)
|
||||||
|
|
||||||
|
|
||||||
Driver = combine_driver(BlockDriver, Mixin)
|
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore
|
||||||
|
"""AIOHTTP Driver"""
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
"""
|
"""[FastAPI](https://fastapi.tiangolo.com/) 驱动适配
|
||||||
## FastAPI 驱动适配
|
|
||||||
|
|
||||||
本驱动同时支持服务端以及客户端连接
|
:::tip 提示
|
||||||
|
本驱动仅支持服务端连接
|
||||||
|
:::
|
||||||
|
|
||||||
后端使用方法请参考: [`FastAPI 文档`](https://fastapi.tiangolo.com/)
|
FrontMatter:
|
||||||
|
sidebar_position: 1
|
||||||
|
description: nonebot.drivers.fastapi 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -39,53 +42,33 @@ def catch_closed(func):
|
|||||||
|
|
||||||
|
|
||||||
class Config(BaseSettings):
|
class Config(BaseSettings):
|
||||||
"""
|
"""FastAPI 驱动框架设置,详情参考 FastAPI 文档"""
|
||||||
FastAPI 驱动框架设置,详情参考 FastAPI 文档
|
|
||||||
"""
|
|
||||||
|
|
||||||
fastapi_openapi_url: Optional[str] = None
|
fastapi_openapi_url: Optional[str] = None
|
||||||
"""
|
"""`openapi.json` 地址,默认为 `None` 即关闭"""
|
||||||
`openapi.json` 地址,默认为 `None` 即关闭
|
|
||||||
"""
|
|
||||||
fastapi_docs_url: Optional[str] = None
|
fastapi_docs_url: Optional[str] = None
|
||||||
"""
|
"""`swagger` 地址,默认为 `None` 即关闭"""
|
||||||
`swagger` 地址,默认为 `None` 即关闭
|
|
||||||
"""
|
|
||||||
fastapi_redoc_url: Optional[str] = None
|
fastapi_redoc_url: Optional[str] = None
|
||||||
"""
|
"""`redoc` 地址,默认为 `None` 即关闭"""
|
||||||
`redoc` 地址,默认为 `None` 即关闭
|
|
||||||
"""
|
|
||||||
fastapi_include_adapter_schema: bool = True
|
fastapi_include_adapter_schema: bool = True
|
||||||
"""
|
"""是否包含适配器路由的 schema,默认为 `True`"""
|
||||||
是否包含适配器路由的 schema,默认为 `True`
|
|
||||||
"""
|
|
||||||
fastapi_reload: bool = False
|
fastapi_reload: bool = False
|
||||||
"""
|
"""开启/关闭冷重载"""
|
||||||
开启/关闭冷重载
|
|
||||||
"""
|
|
||||||
fastapi_reload_dirs: Optional[List[str]] = None
|
fastapi_reload_dirs: Optional[List[str]] = None
|
||||||
"""
|
"""重载监控文件夹列表,默认为 uvicorn 默认值"""
|
||||||
重载监控文件夹列表,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
fastapi_reload_delay: Optional[float] = None
|
fastapi_reload_delay: Optional[float] = None
|
||||||
"""
|
"""重载延迟,默认为 uvicorn 默认值"""
|
||||||
重载延迟,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
fastapi_reload_includes: Optional[List[str]] = None
|
fastapi_reload_includes: Optional[List[str]] = None
|
||||||
"""
|
"""要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值"""
|
||||||
要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
fastapi_reload_excludes: Optional[List[str]] = None
|
fastapi_reload_excludes: Optional[List[str]] = None
|
||||||
"""
|
"""不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值"""
|
||||||
不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
extra = "ignore"
|
extra = "ignore"
|
||||||
|
|
||||||
|
|
||||||
class Driver(ReverseDriver):
|
class Driver(ReverseDriver):
|
||||||
"""FastAPI 驱动框架。包含反向 Server 功能。"""
|
"""FastAPI 驱动框架。"""
|
||||||
|
|
||||||
def __init__(self, env: Env, config: NoneBotConfig):
|
def __init__(self, env: Env, config: NoneBotConfig):
|
||||||
super(Driver, self).__init__(env, config)
|
super(Driver, self).__init__(env, config)
|
||||||
@ -254,6 +237,8 @@ class Driver(ReverseDriver):
|
|||||||
|
|
||||||
|
|
||||||
class FastAPIWebSocket(BaseWebSocket):
|
class FastAPIWebSocket(BaseWebSocket):
|
||||||
|
"""FastAPI WebSocket Wrapper"""
|
||||||
|
|
||||||
@overrides(BaseWebSocket)
|
@overrides(BaseWebSocket)
|
||||||
def __init__(self, *, request: BaseRequest, websocket: WebSocket):
|
def __init__(self, *, request: BaseRequest, websocket: WebSocket):
|
||||||
super().__init__(request=request)
|
super().__init__(request=request)
|
||||||
@ -294,3 +279,6 @@ class FastAPIWebSocket(BaseWebSocket):
|
|||||||
@overrides(BaseWebSocket)
|
@overrides(BaseWebSocket)
|
||||||
async def send_bytes(self, data: bytes) -> None:
|
async def send_bytes(self, data: bytes) -> None:
|
||||||
await self.websocket.send({"type": "websocket.send", "bytes": data})
|
await self.websocket.send({"type": "websocket.send", "bytes": data})
|
||||||
|
|
||||||
|
|
||||||
|
__autodoc__ = {"catch_closed": False}
|
||||||
|
@ -1,4 +1,20 @@
|
|||||||
from typing import AsyncGenerator
|
"""[HTTPX](https://www.python-httpx.org/) 驱动适配
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nb driver install httpx
|
||||||
|
# 或者
|
||||||
|
pip install nonebot2[httpx]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
本驱动仅支持客户端 HTTP 连接
|
||||||
|
:::
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 3
|
||||||
|
description: nonebot.drivers.httpx 模块
|
||||||
|
"""
|
||||||
|
from typing import Type, AsyncGenerator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from nonebot.typing import overrides
|
from nonebot.typing import overrides
|
||||||
@ -9,6 +25,7 @@ from nonebot.drivers import (
|
|||||||
WebSocket,
|
WebSocket,
|
||||||
HTTPVersion,
|
HTTPVersion,
|
||||||
ForwardMixin,
|
ForwardMixin,
|
||||||
|
ForwardDriver,
|
||||||
combine_driver,
|
combine_driver,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,6 +38,8 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
class Mixin(ForwardMixin):
|
class Mixin(ForwardMixin):
|
||||||
|
"""HTTPX Mixin"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(ForwardMixin)
|
@overrides(ForwardMixin)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
@ -57,4 +76,5 @@ class Mixin(ForwardMixin):
|
|||||||
yield ws
|
yield ws
|
||||||
|
|
||||||
|
|
||||||
Driver = combine_driver(BlockDriver, Mixin)
|
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore
|
||||||
|
"""HTTPX Driver"""
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
"""
|
"""[Quart](https://pgjones.gitlab.io/quart/index.html) 驱动适配
|
||||||
## Quart 驱动适配
|
|
||||||
|
|
||||||
后端使用方法请参考: [`Quart 文档`](https://pgjones.gitlab.io/quart/index.html)
|
```bash
|
||||||
|
nb driver install quart
|
||||||
|
# 或者
|
||||||
|
pip install nonebot2[quart]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
本驱动仅支持服务端连接
|
||||||
|
:::
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 5
|
||||||
|
description: nonebot.drivers.quart 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
@ -47,39 +58,25 @@ def catch_closed(func):
|
|||||||
|
|
||||||
|
|
||||||
class Config(BaseSettings):
|
class Config(BaseSettings):
|
||||||
"""
|
"""Quart 驱动框架设置"""
|
||||||
Quart 驱动框架设置
|
|
||||||
"""
|
|
||||||
|
|
||||||
quart_reload: bool = False
|
quart_reload: bool = False
|
||||||
"""
|
"""开启/关闭冷重载"""
|
||||||
开启/关闭冷重载
|
|
||||||
"""
|
|
||||||
quart_reload_dirs: Optional[List[str]] = None
|
quart_reload_dirs: Optional[List[str]] = None
|
||||||
"""
|
"""重载监控文件夹列表,默认为 uvicorn 默认值"""
|
||||||
重载监控文件夹列表,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
quart_reload_delay: Optional[float] = None
|
quart_reload_delay: Optional[float] = None
|
||||||
"""
|
"""重载延迟,默认为 uvicorn 默认值"""
|
||||||
重载延迟,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
quart_reload_includes: Optional[List[str]] = None
|
quart_reload_includes: Optional[List[str]] = None
|
||||||
"""
|
"""要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值"""
|
||||||
要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
quart_reload_excludes: Optional[List[str]] = None
|
quart_reload_excludes: Optional[List[str]] = None
|
||||||
"""
|
"""不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值"""
|
||||||
不要监听的文件列表,支持 glob pattern,默认为 uvicorn 默认值
|
|
||||||
"""
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
extra = "ignore"
|
extra = "ignore"
|
||||||
|
|
||||||
|
|
||||||
class Driver(ReverseDriver):
|
class Driver(ReverseDriver):
|
||||||
"""
|
"""Quart 驱动框架"""
|
||||||
Quart 驱动框架
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, env: Env, config: NoneBotConfig):
|
def __init__(self, env: Env, config: NoneBotConfig):
|
||||||
super().__init__(env, config)
|
super().__init__(env, config)
|
||||||
@ -239,6 +236,8 @@ class Driver(ReverseDriver):
|
|||||||
|
|
||||||
|
|
||||||
class WebSocket(BaseWebSocket):
|
class WebSocket(BaseWebSocket):
|
||||||
|
"""Quart WebSocket Wrapper"""
|
||||||
|
|
||||||
def __init__(self, *, request: BaseRequest, websocket: QuartWebSocket):
|
def __init__(self, *, request: BaseRequest, websocket: QuartWebSocket):
|
||||||
super().__init__(request=request)
|
super().__init__(request=request)
|
||||||
self.websocket = websocket
|
self.websocket = websocket
|
||||||
@ -280,3 +279,6 @@ class WebSocket(BaseWebSocket):
|
|||||||
@overrides(BaseWebSocket)
|
@overrides(BaseWebSocket)
|
||||||
async def send_bytes(self, data: bytes):
|
async def send_bytes(self, data: bytes):
|
||||||
await self.websocket.send(data)
|
await self.websocket.send(data)
|
||||||
|
|
||||||
|
|
||||||
|
__autodoc__ = {"catch_closed": False}
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
|
"""[websockets](https://websockets.readthedocs.io/) 驱动适配
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nb driver install websockets
|
||||||
|
# 或者
|
||||||
|
pip install nonebot2[websockets]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
本驱动仅支持客户端 WebSocket 连接
|
||||||
|
:::
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 4
|
||||||
|
description: nonebot.drivers.websockets 模块
|
||||||
|
"""
|
||||||
import logging
|
import logging
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import AsyncGenerator
|
from typing import Type, AsyncGenerator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from nonebot.typing import overrides
|
from nonebot.typing import overrides
|
||||||
@ -9,7 +25,7 @@ from nonebot.drivers import Request, Response
|
|||||||
from nonebot.exception import WebSocketClosed
|
from nonebot.exception import WebSocketClosed
|
||||||
from nonebot.drivers._block_driver import BlockDriver
|
from nonebot.drivers._block_driver import BlockDriver
|
||||||
from nonebot.drivers import WebSocket as BaseWebSocket
|
from nonebot.drivers import WebSocket as BaseWebSocket
|
||||||
from nonebot.drivers import ForwardMixin, combine_driver
|
from nonebot.drivers import ForwardMixin, ForwardDriver, combine_driver
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from websockets.exceptions import ConnectionClosed
|
from websockets.exceptions import ConnectionClosed
|
||||||
@ -38,6 +54,8 @@ def catch_closed(func):
|
|||||||
|
|
||||||
|
|
||||||
class Mixin(ForwardMixin):
|
class Mixin(ForwardMixin):
|
||||||
|
"""Websockets Mixin"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(ForwardMixin)
|
@overrides(ForwardMixin)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
@ -60,6 +78,8 @@ class Mixin(ForwardMixin):
|
|||||||
|
|
||||||
|
|
||||||
class WebSocket(BaseWebSocket):
|
class WebSocket(BaseWebSocket):
|
||||||
|
"""Websockets WebSocket Wrapper"""
|
||||||
|
|
||||||
@overrides(BaseWebSocket)
|
@overrides(BaseWebSocket)
|
||||||
def __init__(self, *, request: Request, websocket: WebSocketClientProtocol):
|
def __init__(self, *, request: Request, websocket: WebSocketClientProtocol):
|
||||||
super().__init__(request=request)
|
super().__init__(request=request)
|
||||||
@ -103,4 +123,5 @@ class WebSocket(BaseWebSocket):
|
|||||||
await self.websocket.send(data)
|
await self.websocket.send(data)
|
||||||
|
|
||||||
|
|
||||||
Driver = combine_driver(BlockDriver, Mixin)
|
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore
|
||||||
|
"""Websockets Driver"""
|
||||||
|
@ -1,7 +1,37 @@
|
|||||||
"""
|
"""本模块为 NoneBot 插件开发提供便携的定义函数。
|
||||||
## 插件
|
|
||||||
|
|
||||||
为 NoneBot 插件开发提供便携的定义函数。
|
## 快捷导入
|
||||||
|
|
||||||
|
为方便使用,本模块从子模块导入了部分内容,以下内容可以直接通过本模块导入:
|
||||||
|
|
||||||
|
- `on` => {ref}``on` <nonebot.plugin.on.on>`
|
||||||
|
- `on_metaevent` => {ref}``on_metaevent` <nonebot.plugin.on.on_metaevent>`
|
||||||
|
- `on_message` => {ref}``on_message` <nonebot.plugin.on.on_message>`
|
||||||
|
- `on_notice` => {ref}``on_notice` <nonebot.plugin.on.on_notice>`
|
||||||
|
- `on_request` => {ref}``on_request` <nonebot.plugin.on.on_request>`
|
||||||
|
- `on_startswith` => {ref}``on_startswith` <nonebot.plugin.on.on_startswith>`
|
||||||
|
- `on_endswith` => {ref}``on_endswith` <nonebot.plugin.on.on_endswith>`
|
||||||
|
- `on_keyword` => {ref}``on_keyword` <nonebot.plugin.on.on_keyword>`
|
||||||
|
- `on_command` => {ref}``on_command` <nonebot.plugin.on.on_command>`
|
||||||
|
- `on_shell_command` => {ref}``on_shell_command` <nonebot.plugin.on.on_shell_command>`
|
||||||
|
- `on_regex` => {ref}``on_regex` <nonebot.plugin.on.on_regex>`
|
||||||
|
- `CommandGroup` => {ref}``CommandGroup` <nonebot.plugin.on.CommandGroup>`
|
||||||
|
- `Matchergroup` => {ref}``MatcherGroup` <nonebot.plugin.on.MatcherGroup>`
|
||||||
|
- `load_plugin` => {ref}``load_plugin` <nonebot.plugin.load.load_plugin>`
|
||||||
|
- `load_plugins` => {ref}``load_plugins` <nonebot.plugin.load.load_plugins>`
|
||||||
|
- `load_all_plugins` => {ref}``load_all_plugins` <nonebot.plugin.load.load_all_plugins>`
|
||||||
|
- `load_from_json` => {ref}``load_from_json` <nonebot.plugin.load.load_from_json>`
|
||||||
|
- `load_from_toml` => {ref}``load_from_toml` <nonebot.plugin.load.load_from_toml>`
|
||||||
|
- `load_builtin_plugin` => {ref}``load_builtin_plugin` <nonebot.plugin.load.load_builtin_plugin>`
|
||||||
|
- `load_builtin_plugins` => {ref}``load_builtin_plugins` <nonebot.plugin.load.load_builtin_plugins>`
|
||||||
|
- `get_plugin` => {ref}``get_plugin` <nonebot.plugin.plugin.get_plugin>`
|
||||||
|
- `get_loaded_plugins` => {ref}``get_loaded_plugins` <nonebot.plugin.plugin.get_loaded_plugins>`
|
||||||
|
- `export` => {ref}``export` <nonebot.plugin.export.export>`
|
||||||
|
- `require` => {ref}``require` <nonebot.plugin.load.require>`
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 0
|
||||||
|
description: nonebot.plugin 模块
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
|
"""本模块定义了插件导出的内容对象。
|
||||||
|
|
||||||
|
在新版插件系统中,推荐优先使用直接 import 所需要的插件内容。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 4
|
||||||
|
description: nonebot.plugin.export 模块
|
||||||
|
"""
|
||||||
|
|
||||||
from . import _current_plugin
|
from . import _current_plugin
|
||||||
|
|
||||||
|
|
||||||
class Export(dict):
|
class Export(dict):
|
||||||
"""
|
"""插件导出内容以使得其他插件可以获得。
|
||||||
插件导出内容以使得其他插件可以获得。
|
|
||||||
|
|
||||||
用法:
|
用法:
|
||||||
```python
|
```python
|
||||||
@ -42,9 +50,7 @@ class Export(dict):
|
|||||||
|
|
||||||
|
|
||||||
def export() -> Export:
|
def export() -> Export:
|
||||||
"""
|
"""获取当前插件的导出内容对象"""
|
||||||
获取插件的导出内容对象
|
|
||||||
"""
|
|
||||||
plugin = _current_plugin.get()
|
plugin = _current_plugin.get()
|
||||||
if not plugin:
|
if not plugin:
|
||||||
raise RuntimeError("Export outside of the plugin!")
|
raise RuntimeError("Export outside of the plugin!")
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
"""本模块定义插件加载接口。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 1
|
||||||
|
description: nonebot.plugin.load 模块
|
||||||
|
"""
|
||||||
import json
|
import json
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Set, Iterable, Optional
|
from typing import Set, Iterable, Optional
|
||||||
@ -11,8 +17,7 @@ from .plugin import Plugin, get_plugin
|
|||||||
|
|
||||||
|
|
||||||
def load_plugin(module_path: str) -> Optional[Plugin]:
|
def load_plugin(module_path: str) -> Optional[Plugin]:
|
||||||
"""
|
"""加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||||
使用 `PluginManager` 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
module_path: 插件名称 `path.to.your.plugin`
|
module_path: 插件名称 `path.to.your.plugin`
|
||||||
@ -24,11 +29,10 @@ def load_plugin(module_path: str) -> Optional[Plugin]:
|
|||||||
|
|
||||||
|
|
||||||
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
||||||
"""
|
"""导入文件夹下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
导入目录下多个插件,以 `_` 开头的插件不会被导入!
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
plugin_dir: 插件路径
|
plugin_dir: 文件夹路径
|
||||||
"""
|
"""
|
||||||
manager = PluginManager(search_path=plugin_dir)
|
manager = PluginManager(search_path=plugin_dir)
|
||||||
_managers.append(manager)
|
_managers.append(manager)
|
||||||
@ -38,12 +42,11 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
|||||||
def load_all_plugins(
|
def load_all_plugins(
|
||||||
module_path: Iterable[str], plugin_dir: Iterable[str]
|
module_path: Iterable[str], plugin_dir: Iterable[str]
|
||||||
) -> Set[Plugin]:
|
) -> Set[Plugin]:
|
||||||
"""
|
"""导入指定列表中的插件以及指定目录下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
导入指定列表中的插件以及指定目录下多个插件,以 `_` 开头的插件不会被导入!
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
module_path: 指定插件集合
|
module_path: 指定插件集合
|
||||||
plugin_dir: 指定插件路径集合
|
plugin_dir: 指定文件夹路径集合
|
||||||
"""
|
"""
|
||||||
manager = PluginManager(module_path, plugin_dir)
|
manager = PluginManager(module_path, plugin_dir)
|
||||||
_managers.append(manager)
|
_managers.append(manager)
|
||||||
@ -51,12 +54,23 @@ def load_all_plugins(
|
|||||||
|
|
||||||
|
|
||||||
def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
||||||
"""
|
"""导入指定 json 文件中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
导入指定 json 文件中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入!
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
file_path: 指定 json 文件路径
|
file_path: 指定 json 文件路径
|
||||||
encoding: 指定 json 文件编码
|
encoding: 指定 json 文件编码
|
||||||
|
|
||||||
|
用法:
|
||||||
|
```json title=plugins.json
|
||||||
|
{
|
||||||
|
"plugins": ["some_plugin"],
|
||||||
|
"plugin_dirs": ["some_dir"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
nonebot.load_from_json("plugins.json")
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
with open(file_path, "r", encoding=encoding) as f:
|
with open(file_path, "r", encoding=encoding) as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
@ -68,13 +82,22 @@ def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
|||||||
|
|
||||||
|
|
||||||
def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
||||||
"""
|
"""导入指定 toml 文件 `[tool.nonebot]` 中的 `plugins` 以及 `plugin_dirs` 下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
导入指定 toml 文件 `[tool.nonebot]` 中的 `plugins` 以及 `plugin_dirs` 下多个插件,
|
|
||||||
以 `_` 开头的插件不会被导入!
|
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
file_path: 指定 toml 文件路径
|
file_path: 指定 toml 文件路径
|
||||||
encoding: 指定 toml 文件编码
|
encoding: 指定 toml 文件编码
|
||||||
|
|
||||||
|
用法:
|
||||||
|
```toml title=pyproject.toml
|
||||||
|
[tool.nonebot]
|
||||||
|
plugins = ["some_plugin"]
|
||||||
|
plugin_dirs = ["some_dir"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
nonebot.load_from_toml("pyproject.toml")
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
with open(file_path, "r", encoding=encoding) as f:
|
with open(file_path, "r", encoding=encoding) as f:
|
||||||
data = tomlkit.parse(f.read()) # type: ignore
|
data = tomlkit.parse(f.read()) # type: ignore
|
||||||
@ -97,25 +120,30 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
|
|||||||
|
|
||||||
|
|
||||||
def load_builtin_plugin(name: str) -> Optional[Plugin]:
|
def load_builtin_plugin(name: str) -> Optional[Plugin]:
|
||||||
"""
|
"""导入 NoneBot 内置插件。
|
||||||
导入 NoneBot 内置插件
|
|
||||||
|
参数:
|
||||||
|
name: 插件名称
|
||||||
"""
|
"""
|
||||||
return load_plugin(f"nonebot.plugins.{name}")
|
return load_plugin(f"nonebot.plugins.{name}")
|
||||||
|
|
||||||
|
|
||||||
def load_builtin_plugins(*plugins) -> Set[Plugin]:
|
def load_builtin_plugins(*plugins) -> Set[Plugin]:
|
||||||
"""
|
"""导入多个 NoneBot 内置插件。
|
||||||
导入多个 NoneBot 内置插件
|
|
||||||
|
参数:
|
||||||
|
plugins: 插件名称列表
|
||||||
"""
|
"""
|
||||||
return load_all_plugins([f"nonebot.plugins.{p}" for p in plugins], [])
|
return load_all_plugins([f"nonebot.plugins.{p}" for p in plugins], [])
|
||||||
|
|
||||||
|
|
||||||
def require(name: str) -> Export:
|
def require(name: str) -> Export:
|
||||||
"""
|
"""获取一个插件的导出内容。
|
||||||
获取一个插件的导出内容
|
|
||||||
|
如果为 `load_plugins` 文件夹导入的插件,则为文件(夹)名。
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
name: 插件名,与 `load_plugin` 参数一致。如果为 `load_plugins` 导入的插件,则为文件(夹)名。
|
name: 插件名,即 {ref}`nonebot.plugin.plugin.Plugin.name`。
|
||||||
|
|
||||||
异常:
|
异常:
|
||||||
RuntimeError: 插件无法加载
|
RuntimeError: 插件无法加载
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
"""本模块实现插件加载流程。
|
||||||
|
|
||||||
|
参考: [import hooks](https://docs.python.org/3/reference/import.html#import-hooks), [PEP302](https://www.python.org/dev/peps/pep-0302/)
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 5
|
||||||
|
description: nonebot.plugin.manager 模块
|
||||||
|
"""
|
||||||
import sys
|
import sys
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import importlib
|
import importlib
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
"""本模块定义事件响应器便携定义函数。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 2
|
||||||
|
description: nonebot.plugin.on 模块
|
||||||
|
"""
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
"""本模块定义插件对象。
|
||||||
|
|
||||||
|
FrontMatter:
|
||||||
|
sidebar_position: 3
|
||||||
|
description: nonebot.plugin.plugin 模块
|
||||||
|
"""
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from dataclasses import field, dataclass
|
from dataclasses import field, dataclass
|
||||||
from typing import TYPE_CHECKING, Set, Dict, Type, Optional
|
from typing import TYPE_CHECKING, Set, Dict, Type, Optional
|
||||||
@ -10,9 +16,7 @@ if TYPE_CHECKING:
|
|||||||
from .manager import PluginManager
|
from .manager import PluginManager
|
||||||
|
|
||||||
plugins: Dict[str, "Plugin"] = {}
|
plugins: Dict[str, "Plugin"] = {}
|
||||||
"""
|
"""已加载的插件"""
|
||||||
已加载的插件
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(eq=False)
|
@dataclass(eq=False)
|
||||||
@ -20,53 +24,36 @@ class Plugin(object):
|
|||||||
"""存储插件信息"""
|
"""存储插件信息"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
"""
|
"""插件名称,使用 文件/文件夹 名称作为插件名"""
|
||||||
插件名称,使用 文件/文件夹 名称作为插件名
|
|
||||||
"""
|
|
||||||
module: ModuleType
|
module: ModuleType
|
||||||
"""
|
"""插件模块对象"""
|
||||||
插件模块对象
|
|
||||||
"""
|
|
||||||
module_name: str
|
module_name: str
|
||||||
"""
|
"""点分割模块路径"""
|
||||||
点分割模块路径
|
|
||||||
"""
|
|
||||||
manager: "PluginManager"
|
manager: "PluginManager"
|
||||||
"""
|
"""导入该插件的插件管理器"""
|
||||||
导入该插件的插件管理器
|
|
||||||
"""
|
|
||||||
export: Export = field(default_factory=Export)
|
export: Export = field(default_factory=Export)
|
||||||
"""
|
"""插件内定义的导出内容"""
|
||||||
插件内定义的导出内容
|
|
||||||
"""
|
|
||||||
matcher: Set[Type[Matcher]] = field(default_factory=set)
|
matcher: Set[Type[Matcher]] = field(default_factory=set)
|
||||||
"""
|
"""插件内定义的 `Matcher`"""
|
||||||
插件内定义的 `Matcher`
|
|
||||||
"""
|
|
||||||
parent_plugin: Optional["Plugin"] = None
|
parent_plugin: Optional["Plugin"] = None
|
||||||
"""
|
"""父插件"""
|
||||||
父插件
|
|
||||||
"""
|
|
||||||
sub_plugins: Set["Plugin"] = field(default_factory=set)
|
sub_plugins: Set["Plugin"] = field(default_factory=set)
|
||||||
"""
|
"""子插件集合"""
|
||||||
子插件集合
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_plugin(name: str) -> Optional[Plugin]:
|
def get_plugin(name: str) -> Optional[Plugin]:
|
||||||
"""
|
"""获取已经导入的某个插件。
|
||||||
获取当前导入的某个插件。
|
|
||||||
|
如果为 `load_plugins` 文件夹导入的插件,则为文件(夹)名。
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
name: 插件名,与 `load_plugin` 参数一致。如果为 `load_plugins` 导入的插件,则为文件(夹)名。
|
name: 插件名,即 {ref}`nonebot.plugin.plugin.Plugin.name`。
|
||||||
"""
|
"""
|
||||||
return plugins.get(name)
|
return plugins.get(name)
|
||||||
|
|
||||||
|
|
||||||
def get_loaded_plugins() -> Set[Plugin]:
|
def get_loaded_plugins() -> Set[Plugin]:
|
||||||
"""
|
"""获取当前已导入的所有插件。"""
|
||||||
获取当前已导入的所有插件。
|
|
||||||
"""
|
|
||||||
return set(plugins.values())
|
return set(plugins.values())
|
||||||
|
|
||||||
|
|
||||||
|
8
poetry.lock
generated
8
poetry.lock
generated
@ -721,7 +721,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyparsing"
|
name = "pyparsing"
|
||||||
version = "3.0.6"
|
version = "3.0.7"
|
||||||
description = "Python parsing module"
|
description = "Python parsing module"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@ -1109,7 +1109,7 @@ websockets = ["websockets"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7.3"
|
python-versions = "^3.7.3"
|
||||||
content-hash = "0e101f22381597b968f6c51419c1aa284243183f7298ac7837f125510e5a7a53"
|
content-hash = "b18b98c20de891dfd80f15ac896f13ed529264dd4913ed1ca9cccff3fee379ba"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiodns = [
|
aiodns = [
|
||||||
@ -1848,8 +1848,8 @@ pygtrie = [
|
|||||||
{file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"},
|
{file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"},
|
||||||
]
|
]
|
||||||
pyparsing = [
|
pyparsing = [
|
||||||
{file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
|
{file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"},
|
||||||
{file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
|
{file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"},
|
||||||
]
|
]
|
||||||
pytest = [
|
pytest = [
|
||||||
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
|
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
|
||||||
|
@ -30,7 +30,7 @@ tomlkit = "^0.7.0"
|
|||||||
fastapi = "^0.70.0"
|
fastapi = "^0.70.0"
|
||||||
typing-extensions = ">=3.10.0,<5.0.0"
|
typing-extensions = ">=3.10.0,<5.0.0"
|
||||||
Quart = { version = "^0.16.0", optional = true }
|
Quart = { version = "^0.16.0", optional = true }
|
||||||
websockets = { version=">=9.1", optional = true }
|
websockets = { version="^10.0", optional = true }
|
||||||
pydantic = { version = "~1.9.0", extras = ["dotenv"] }
|
pydantic = { version = "~1.9.0", extras = ["dotenv"] }
|
||||||
uvicorn = { version = "^0.15.0", extras = ["standard"] }
|
uvicorn = { version = "^0.15.0", extras = ["standard"] }
|
||||||
aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true }
|
aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true }
|
||||||
|
Loading…
Reference in New Issue
Block a user