简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

ErisPulse.Core.adapter 模块


模块概述

ErisPulse 适配器系统

提供平台适配器管理功能。支持多平台消息处理、事件驱动和生命周期管理。


类列表

class AdapterManager(ManagerBase)

适配器管理器

管理多个平台适配器的注册、启动和关闭,提供与模块管理器一致的接口

提示

  1. 通过register方法注册适配器
  2. 通过startup方法启动适配器
  3. 通过shutdown方法关闭所有适配器
  4. 通过on装饰器注册OneBot12协议事件处理器

方法列表

_extract_message_text(data: Any)

内部方法 从事件 message 段提取纯文本(仅 text 段拼接),无文本时返回空串


_warn_deprecated_kwarg(owner: str, old: str, new: str)

内部方法 当检测到使用已弃用的旧关键字参数时,记录一次弃用日志并说明迁移方式


_shutdown_timeout()

内部方法 读取适配器 shutdown 优雅收尾的超时(秒)

复用 ErisPulse.framework.uninit_timeout 配置(反初始化流程的统一超时预算); 未配置或非法时回退常量默认值。

返回值: 超时秒数(>0)


set_sdk_ref(sdk)

设置 SDK 引用


_register_config_change_routing()

内部方法 注册 config.set / config.updated 事件订阅,将配置变更路由到各适配器的 on_config_update


_register_dependency_routing()

内部方法 注册 module.load / module.unload 事件订阅,将模块就绪/丢失路由到 声明了依赖的适配器的 on_dependency_ready / on_dependency_lost 钩子


_dependency_watchers(module_name: str)

内部方法 找出关注指定模块的已注册适配器(软依赖或硬依赖均可收到通知)


async _dispatch_dependency_event(module_name: str, hook_name: str)

内部方法 向关注指定模块的适配器分发依赖事件钩子


async _on_module_load_notify(data: dict)

内部方法 处理 module.load 事件:通知依赖该模块的适配器(on_dependency_ready)


async _on_module_unload_notify(data: dict)

内部方法 处理 module.unload 事件:通知依赖该模块的适配器(on_dependency_lost)


_extract_module_name(data: dict)

内部方法 从生命周期事件数据中提取模块名

兼容两种事件形状:直接 emit 的扁平 dict({"module_name": ...}) 与 submit_event 包装的标准事件({"data": {"module_name": ...}})。


_check_missing_dependencies(adapter: 'BaseAdapter', platform: str)

内部方法 检查适配器硬依赖是否就绪(适配器 + 模块均已注册)


_on_config_set(data: dict)

内部方法 处理 config.set 事件:找出受影响的适配器并触发 on_config_update


_on_config_updated(data: dict)

内部方法 处理 config.updated 事件:对比新旧配置树,找出配置变化的适配器并触发 on_config_update


_resolve_config_key(instance: Any)

内部方法 解析适配器的配置键名(优先用 _get_config_key,回退类名)


_notify_config_update(instance: Any, platform: str | None, old_dict: dict | None, new_dict: dict | None)

内部方法 调用适配器的 on_config_update 回调,传入类型安全的配置对象


register(name: str | None = None, class_type: type[BaseAdapter] | None = None, info: dict | None = None)

注册新的适配器类(标准化注册方法)

示例:

>>> adapter.register("MyPlatform", MyPlatformAdapter)

async startup(platforms: str | list[str] | None = None)

启动指定的适配器

示例:

>>> # 启动所有适配器
>>> await adapter.startup()
>>> # 启动单个适配器
>>> await adapter.startup("Platform1")
>>> # 启动多个适配器
>>> await adapter.startup(["Platform1", "Platform2"])

_refresh_accounts_cache(adapter: BaseAdapter, platform: str | None = None)

内部方法 刷新适配器账户缓存,确保配置变更后 _accounts_data 不过期


async _run_adapter(adapter: BaseAdapter, platform: str)

内部方法 运行适配器实例


async shutdown(platforms: str | list[str] | None = None)

关闭指定的适配器

示例:

>>> # 关闭所有适配器
>>> await adapter.shutdown()
>>> # 关闭单个适配器
>>> await adapter.shutdown("Platform1")
>>> # 关闭多个适配器
>>> await adapter.shutdown(["Platform1", "Platform2"])

async _stop_adapter(platform: str)

内部方法 停止单个平台适配器——shutdown 即清理。

将"停止适配器"与"回收其注册的资源"绑定在一次调用里:调用适配器自身的 shutdown() 后立即清理该平台的路由/事件/命令。restart、启动失败重试等 场景均经此入口,保证适配器一旦停止、归属资源必被回收,无需调用方再补清理。

对未注册的平台直接返回;shutdown() 与清理均幂等,半途失败的重试场景 也能正确回收 start() 期间已注册的资源。shutdown() 带优雅收尾超时 (unload_timeout),卡死时强制进入清理,避免阻塞重启/关闭链路。


async _drain_pending_handler_tasks(timeout: float = DEFAULT_HANDLER_DRAIN_TIMEOUT_SECS)

内部方法 等待或取消所有在途的事件处理器 Task


async _cleanup_adapter_resources(platform: str)

内部方法 适配器资源兜底清理(与模块卸载对齐颗粒度)。

清理该平台在运行期间注册的所有路由、命令与事件处理器,并兜底取消 该平台名下的后台任务。同时覆盖两种注册方式:


async restart(platform: str)

重启指定平台适配器(shutdown + 资源兜底清理 + start)

框架自动处理该平台在运行期间注册的路由/事件/命令清理(与模块卸载对齐颗粒度), 并在重启时注入 owner,使新注册的资源可被后续按 owner 清理。 第三方模块(如 Dashboard)的热重载应调用本方法,而非直接操作适配器实例。

示例:

>>> await sdk.adapter.restart("OneBot11")

async unload(platform: str)

卸载并注销单个平台适配器

与 shutdown()(仅停止)不同,unload() 在停止并清理资源后, 额外从管理器注销该平台(释放适配器实例与类引用),用于动态移除适配器 并回收其内存占用。若同一实例还注册了其它平台,实例会保留(仅注销该平台)。

>>> await adapter.unload("MyPlatform")

clear()

清除所有适配器实例和信息

内部方法 此方法用于反初始化时完全重置适配器管理器状态


_config_register(platform: str, enabled: bool = DEFAULT_ADAPTER_ENABLED)

注册新平台适配器(仅当平台不存在时注册)


exists(name: str | None = None)

检查平台是否已注册


is_enabled(name: str | None = None)

检查平台适配器是否启用


enable(name: str | None = None)

启用平台适配器


disable(name: str | None = None)

禁用平台适配器


unregister(name: str | None = None)

取消注册适配器


list_registered()

列出所有已注册的平台

返回值: 平台名称列表


list_items()

列出所有平台适配器状态

合并配置项与已注册适配器,确保禁用适配器也可见。

返回值 ({平台名:): 是否启用} 字典


list_adapters()

兼容性方法 - 保持向后兼容

返回值 ({平台名:): 是否启用} 字典

已弃用 此方法已弃用,请使用 list_items() 代替


on(event_type: str = '*')

OneBot12协议事件监听装饰器

返回值 (装饰器函数): 示例:

>>> # 监听OneBot12标准事件(所有平台)
>>> @sdk.adapter.on("message")
>>> async def handle_message(data):
>>>     print(f"收到OneBot12消息: {data}")
>>>
>>> # 监听特定平台的OneBot12标准事件
>>> @sdk.adapter.on("message", platform="onebot11")
>>> async def handle_onebot11_message(data):
>>>     print(f"收到OneBot11标准消息: {data}")
>>>
>>> # 监听平台原生事件
>>> @sdk.adapter.on("message", raw=True, platform="onebot11")
>>> async def handle_raw_message(data):
>>>     print(f"收到OneBot11原生事件: {data}")
>>>
>>> # 只监听群消息
>>> @sdk.adapter.on("message", detail_type="group")
>>> async def handle_group_message(data):
>>>     print(f"收到群消息: {data}")
>>>
>>> # 只监听以 "签到" 开头的消息(文本匹配)
>>> @sdk.adapter.on("message", pattern="签到*")
>>> async def handle_signin(data):
>>>     print(f"收到签到消息: {data}")

middleware(func: Callable)

添加OneBot12中间件处理器

注册期间若处于模块加载上下文(current_owner 已设置),自动记录归属, 模块卸载时随处理器一并移除。

中间件在事件分发前顺序执行,返回契约:

>>> @sdk.adapter.middleware
>>> async def onebot_middleware(data):
>>>     if _is_banned(data):
>>>         return False  # 否决:事件被丢弃(防火墙 / 限流场景)
>>>     data["rate_marked"] = True
>>>     return data

unregister_handlers_by_owner(owner: str)

移除指定归属者注册的全部事件处理器与中间件

覆盖三类资源(均在注册期间记录了 owner):

供模块卸载时移除该模块的处理器(避免卸载后仍被分发触发), 以及适配器关闭 / 重启时清理旧实例自有的处理器。


async emit(data: Any)

提交OneBot12协议事件到指定平台

每个事件处理器(handler)都在独立的 asyncio.Task 中执行, 单个处理器阻塞不会影响框架的事件分发和其他处理器运行。

>>> await sdk.adapter.emit({
>>>     "id": "123",
>>>     "time": 1620000000,
>>>     "type": "message",
>>>     "detail_type": "private",
>>>     "message": [{"type": "text", "data": {"text": "Hello"}}],
>>>     "platform": "myplatform",
>>>     "myplatform_raw": {...平台原生事件数据...},
>>>     "myplatform_raw_type": "text_message"
>>> })

_dedupe_enabled()

内部方法 读取事件去重开关(ErisPulse.framework.event_dedupe,默认开启)

测试环境普遍使用固定 id 的合成事件且同一用例内连续多次 emit, 可通过配置或直接置 adapter._event_dedupe_enabled = False 关闭。

返回值: 是否启用幂等去重


_is_duplicate_event(event_id: str)

内部方法 事件幂等去重判定(LRU 记录已分发的事件 id)

平台 websocket 重连后重推同一事件(相同 event["id"])时只分发一次; 容量上限 DEFAULT_EVENT_DEDUPE_CAPACITY,超出后淘汰最早记录。


async _emit_dispatch(data: Any, platform: str, event_type: str, detail_type: str, platform_raw: Any, raw_event_type: Any, trace_id: str)

内部方法 emit 的事件分发主体(trace-id 上下文内执行)


_is_handler_scope_allowed(handler_wrapper: dict, data: dict)

内部方法 判断 OneBot12 / 原生事件处理器是否通过模块作用域检查

框架级总线处理器(scope_exempt 或 owner 为空)始终放行; 模块级处理器按 owner 与当前事件所属平台/Bot 判定。


_is_handler_match(handler_wrapper: dict, data: dict, detail_type: str, raw: bool = False)

内部方法 判断处理器是否匹配事件的 detail_type / 文本条件

未设置条件(None)即视为命中;pattern 与 regex 只对消息类事件 生效(原生事件无 message 段,文本条件自动跳过)。


_get_handler_semaphore()

内部方法 获取事件处理器并发控制信号量

懒初始化,首次调用时从框架配置读取 handler_max_concurrency。 配置变更后可通过设置 _handler_max_concurrency = 0 来强制重建。

返回值 (asyncio.Semaphore): 并发控制信号量


_on_framework_config_changed(_data: dict)

内部方法 framework 配置变更回调:handler_max_concurrency 变化时失效缓存的信号量, 下次 _get_handler_semaphore 将按新值重建。


_dispatch_handler_task(func: Callable, data: Any)

内部方法 将事件处理器包装为独立 asyncio.Task 并调度执行

处理器在独立 Task 中运行,不会阻塞 adapter.emit() 的后续流程。 自动捕获处理器异常并记录日志,同时监控处理器执行耗时。


_auto_register_bot(platform: str, self_info: dict)

内部方法 自动注册Bot(从OB12事件self字段提取),提取所有扩展字段作为Bot元信息

self字段标准扩展:


_update_bot_status(platform: str, bot_id: str, status: str)

内部方法 更新Bot状态


_update_bot_heartbeat(platform: str, self_info: dict)

内部方法 更新Bot心跳(更新活跃时间和元信息)


_evict_offline_bots(expiry_secs: int | None = None)

内部方法 清除过期的离线 Bot 记录

遍历 _bots,将状态为 offline 且 last_active 距今超过 expiry_secs 的条目移除。


get_bot_info(platform: str, bot_id: str)

获取Bot详细信息

>>> info = adapter.get_bot_info("telegram", "123456")
>>> # {"status": "online", "last_active": 1712345678.0, "info": {"nickname": "MyBot"}}

list_bots(platform: str | None = None)

列出Bot信息

示例:

>>> # 列出所有Bot
>>> all_bots = adapter.list_bots()
>>> # 列出指定平台的Bot
>>> tg_bots = adapter.list_bots("telegram")

is_bot_online(platform: str, bot_id: str)

检查Bot是否在线

>>> if adapter.is_bot_online("telegram", "123456"):
...     print("Bot在线")

get_status_summary()

获取适配器与Bot的完整状态摘要

返回所有适配器的运行状态及各适配器下的Bot状态,便于WebUI展示。 包含已禁用适配器以便于管理。

返回值 (状态摘要字典): 示例:

>>> summary = adapter.get_status_summary()
>>> # {
>>> #     "adapters": {
>>> #         "telegram": {
>>> #             "status": "started",
>>> #             "bots": {
>>> #                 "123456": {
>>> #                     "status": "online",
>>> #                     "last_active": 1712345678.0,
>>> #                     "info": {"nickname": "MyBot"}
>>> #                 }
>>> #             }
>>> #         },
>>> #         "disabled_platform": {
>>> #             "status": "disabled",
>>> #             "enabled": False,
>>> #             "bots": {}
>>> #         }
>>> #     }
>>> # }

get_topology()

获取适配器与 Bot 的拓扑树数据(便于 WebUI 展示)

聚合每个适配器的运行状态、下属 Bot 状态,以及平台级 / Bot 级 模块作用域绑定,展示"适配器 → Bot → 作用域"的归属关系。

返回值 (拓扑树字典): {"adapters": {platform: { "status": str, "enabled": bool, "bots": {bot_id: {"status", "last_active", "info", "scope"}}, "scope": {"modules": [...], "blocked": [...]}, }}}

示例:

>>> topology = adapter.get_topology()
>>> print(topology["adapters"]["onebot11"]["bots"])
{"123456": {...}}

get(name: str | None = None)

获取指定平台的适配器实例

示例:

>>> adapter = adapter.get("MyPlatform")

is_running(name: str | None = None)

检查适配器是否正在运行(已启动)

>>> if adapter.is_running("onebot11"):
>>>     print("onebot11 适配器正在运行")

list_running()

列出所有正在运行的适配器(已启动)

返回值 (平台名称列表): 示例:

>>> running = adapter.list_running()
>>> print("正在运行的适配器:", running)

get_connection_info(platform: str)

获取适配器的连接信息(路由URL、状态等)

结合路由管理器的路由数据,返回指定平台适配器的完整连接信息, 包括 base_url、HTTP 路由、WebSocket 路由和 SSE 路由的完整 URL。

路由注册时的 module_name 必须与适配器的 platform 名称完全一致, 否则路由信息将无法被正确关联。

示例:

>>> info = sdk.adapter.get_connection_info("onebot11")
>>> # {
>>> #     "platform": "onebot11",
>>> #     "status": "started",
>>> #     "connection": {
>>> #         "base_url": "http://localhost:8080",
>>> #         "http_routes": [
>>> #             {"path": "/onebot11/webhook", "method": "POST",
>>> #              "url": "http://localhost:8080/onebot11/webhook"}
>>> #         ],
>>> #         "websocket_routes": [
>>> #             {"path": "/onebot11/ws",
>>> #              "url": "ws://localhost:8080/onebot11/ws"}
>>> #         ],
>>> #         "sse_routes": [
>>> #             {"path": "/onebot11/events",
>>> #              "url": "http://localhost:8080/onebot11/events"}
>>> #         ]
>>> #     }
>>> # }

list_sends(platform: str)

列出指定平台支持的发送方法

包含标准发送方法(Text/Image/Voice/Video/File/Raw_ob12)和平台特有方法, 排除链式修饰方法(At/To/Hook/Retry 等)和属性。

示例:

>>> methods = adapter.list_sends("onebot11")
>>> print(methods)  # ["File", "Image", "Raw_ob12", "Text", "Video", "Voice", ...]

send_info(platform: str, method_name: str)

获取指定发送方法的详细信息

示例:

>>> info = adapter.send_info("onebot11", "Text")
>>> print(info)
# {
#     "name": "Text",
#     "parameters": [
#         {"name": "text", "type": "str", "default": null, "annotation": "str"}
#     ],
#     "return_type": "Awaitable[Any]",
#     "docstring": "发送文本消息..."
# }

platforms()

获取所有已注册的平台列表

返回值 (平台名称列表): 示例:

>>> print("已注册平台:", adapter.platforms)

__getattr__(platform: str)

通过属性访问获取适配器实例


__contains__(platform: str)

检查平台是否存在且处于启用状态