FastAPI
提供 HTTP API。
允许插件通过挂载 子应用 的方式,提供统一的接口。
快速开始
总地来说,您需要在您的插件中做两件事:
- 加载时检查 FastAPI 状态,如已准备好,则直接挂载子应用。
- 注册 COLLECT 事件的监听器,以便准备好时挂载子应用。
具体地说,您需要添加以下代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/test")
async def test():
return "Hello, world!"
def on_load(server, prev_module):
# mount if fastapi_mcdr is ready
fastapi_mcdr = server.get_plugin_instance('fastapi_mcdr')
if fastapi_mcdr is not None and fastapi_mcdr.is_ready():
mount_app(server)
# register event listener
server.register_event_listener(
fastapi_mcdr.COLLECT_EVENT,
mount_app
)
def on_unload(server):
# save plugin id and fastapi_mcdr instance
id_ = server.get_self_metadata().id
fastapi_mcdr = server.get_plugin_instance('fastapi_mcdr')
# unmount app
fastapi_mcdr.unmount(id_)
def mount_app(server):
# save plugin id and fastapi_mcdr instance
id_ = server.get_self_metadata().id
fastapi_mcdr = server.get_plugin_instance('fastapi_mcdr')
# mount app
fastapi_mcdr.mount(id_, app)
访问 http://localhost:8080/docs 即可查看 API 文档,各插件的子应用文档则需要访问 http://localhost:8080/plugin_id/docs。
技术细节
加载
理论上来说,对外提供 HTTP API 应当是一种可选功能,这便是需要检查 FastAPI 状态并同时注册 COLLECT 事件监听器的原因。下图展示了 FastAPI 插件和自定义插件先后加载的流程图:
先加载 FastAPI,再加载自定义插件:
sequenceDiagram
participant FastAPI
participant Test
Note right of FastAPI: FastAPI 加载
Note right of FastAPI: FastAPI 分发 COLLECT 事件
Note left of Test: Test 加载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: Yes!
Test ->> FastAPI: is_ready?
FastAPI ->> Test: Yes!
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 注册 COLLECT 事件
sequenceDiagram
participant FastAPI
participant Test
Note right of FastAPI: FastAPI 加载
Note right of FastAPI: FastAPI 分发 COLLECT 事件
Note left of Test: Test 加载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: Yes!
Test ->> FastAPI: is_ready?
FastAPI ->> Test: Yes!
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 注册 COLLECT 事件
先加载自定义插件,再加载 FastAPI:
sequenceDiagram
participant FastAPI
participant Test
Note left of Test: Test 加载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: No!
Note left of Test: Test 注册 COLLECT 事件
Note right of FastAPI: FastAPI 加载
FastAPI ->> Test: 分发 COLLECT 事件
Test ->> FastAPI: 挂载子应用
sequenceDiagram
participant FastAPI
participant Test
Note left of Test: Test 加载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: No!
Note left of Test: Test 注册 COLLECT 事件
Note right of FastAPI: FastAPI 加载
FastAPI ->> Test: 分发 COLLECT 事件
Test ->> FastAPI: 挂载子应用
通过这个设计,即可实现插件的软依赖,且无需考虑插件加载顺序的问题。下图展示了任意插件重载的情况:
sequenceDiagram
participant FastAPI
participant Test
Note right of FastAPI: FastAPI 重载
FastAPI ->> Test: 分发 COLLECT 事件
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 重载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: Yes!
Test ->> FastAPI: is_ready?
FastAPI ->> Test: Yes!
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 注册 COLLECT 事件
sequenceDiagram
participant FastAPI
participant Test
Note right of FastAPI: FastAPI 重载
FastAPI ->> Test: 分发 COLLECT 事件
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 重载
Test ->> FastAPI: 已加载?
FastAPI ->> Test: Yes!
Test ->> FastAPI: is_ready?
FastAPI ->> Test: Yes!
Test ->> FastAPI: 挂载子应用
Note left of Test: Test 注册 COLLECT 事件
标准
COLLECT 事件
事件名:fastapi_mcdr.collect
该事件的 PluginEvent
实例也会以 COLLECT_EVENT
名公开。
公开函数
is_ready
插件准备好接受挂载的状态,如强行挂载则会抛出一个 RuntimeError
。
mount
参数:
plugin_id
:插件 id。app
:FastAPI 应用。
子应用会挂载在 /<plugin_id>
路径下,文档可以通过访问 /<plugin_id>/docs
查看。
参阅:子应用 - 挂载
unmount
参数:
plugin_id
:插件 id。
卸载指定插件的子应用。