From 37f55652d9cb369b0638e5690177b65f4f715154 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 27 Nov 2021 12:16:31 +0800 Subject: [PATCH] :recycle: separate fastapi driver --- docs/api/drivers/fastapi.md | 34 +++++++-- nonebot/dependencies/__init__.py | 2 +- nonebot/drivers/fastapi.py | 118 ++++++++++++++++++------------- tests/.env.dev | 2 +- 4 files changed, 99 insertions(+), 57 deletions(-) diff --git a/docs/api/drivers/fastapi.md b/docs/api/drivers/fastapi.md index 7bc06ae1..ac7cc77b 100644 --- a/docs/api/drivers/fastapi.md +++ b/docs/api/drivers/fastapi.md @@ -141,9 +141,9 @@ FastAPI 驱动框架设置,详情参考 FastAPI 文档 ## _class_ `Driver` -基类:[`nonebot.drivers.ReverseDriver`](README.md#nonebot.drivers.ReverseDriver), [`nonebot.drivers.ForwardDriver`](README.md#nonebot.drivers.ForwardDriver) +基类:[`nonebot.drivers.ReverseDriver`](README.md#nonebot.drivers.ReverseDriver) -FastAPI 驱动框架 +FastAPI 驱动框架。包含反向 Server 功能。 * **上报地址** @@ -192,6 +192,31 @@ fastapi 使用的 logger 参考文档: [Events](https://fastapi.tiangolo.com/advanced/events/#startup-event) +### `run(host=None, port=None, *, app=None, **kwargs)` + +使用 `uvicorn` 启动 FastAPI + + +## _class_ `FullDriver` + +基类:[`nonebot.drivers.ForwardDriver`](README.md#nonebot.drivers.ForwardDriver), `nonebot.drivers.fastapi.Driver` + +完整的 FastAPI 驱动框架,包含正向 Client 支持和反向 Server 支持。 + + +* **使用方法** + + +```dotenv +DRIVER=nonebot.drivers.fastapi:FullDriver +``` + + +### _property_ `type` + +驱动名称: `fastapi_full` + + ### `setup_http_polling(setup)` @@ -224,11 +249,6 @@ fastapi 使用的 logger -### `run(host=None, port=None, *, app=None, **kwargs)` - -使用 `uvicorn` 启动 FastAPI - - ## _class_ `WebSocket` 基类:[`nonebot.drivers.WebSocket`](README.md#nonebot.drivers.WebSocket) diff --git a/nonebot/dependencies/__init__.py b/nonebot/dependencies/__init__.py index c32a9ffe..80db9840 100644 --- a/nonebot/dependencies/__init__.py +++ b/nonebot/dependencies/__init__.py @@ -1,6 +1,6 @@ """ 依赖注入处理模块 -=============== +================ 该模块实现了依赖注入的定义与处理。 """ diff --git a/nonebot/drivers/fastapi.py b/nonebot/drivers/fastapi.py index db9abf41..2afb082a 100644 --- a/nonebot/drivers/fastapi.py +++ b/nonebot/drivers/fastapi.py @@ -134,9 +134,9 @@ class Config(BaseSettings): extra = "ignore" -class Driver(ReverseDriver, ForwardDriver): +class Driver(ReverseDriver): """ - FastAPI 驱动框架 + FastAPI 驱动框架。包含反向 Server 功能。 :上报地址: @@ -147,13 +147,9 @@ class Driver(ReverseDriver, ForwardDriver): """ def __init__(self, env: Env, config: NoneBotConfig): - super().__init__(env, config) + super(Driver, self).__init__(env, config) self.fastapi_config: Config = Config(**config.dict()) - self.http_pollings: List[HTTPPOLLING_SETUP] = [] - self.websockets: List[WEBSOCKET_SETUP] = [] - self.shutdown: asyncio.Event = asyncio.Event() - self.connections: List[asyncio.Task] = [] self._server_app = FastAPI( debug=config.debug, @@ -167,9 +163,6 @@ class Driver(ReverseDriver, ForwardDriver): self._server_app.websocket("/{adapter}/ws")(self._handle_ws_reverse) self._server_app.websocket("/{adapter}/ws/")(self._handle_ws_reverse) - self.on_startup(self._run_forward) - self.on_shutdown(self._shutdown_forward) - @property @overrides(ReverseDriver) def type(self) -> str: @@ -204,32 +197,6 @@ class Driver(ReverseDriver, ForwardDriver): """参考文档: `Events `_""" return self.server_app.on_event("shutdown")(func) - @overrides(ForwardDriver) - def setup_http_polling(self, setup: HTTPPOLLING_SETUP) -> None: - """ - :说明: - - 注册一个 HTTP 轮询连接,如果传入一个函数,则该函数会在每次连接时被调用 - - :参数: - - * ``setup: Union[HTTPPollingSetup, Callable[[], Awaitable[HTTPPollingSetup]]]`` - """ - self.http_pollings.append(setup) - - @overrides(ForwardDriver) - def setup_websocket(self, setup: WEBSOCKET_SETUP) -> None: - """ - :说明: - - 注册一个 WebSocket 连接,如果传入一个函数,则该函数会在每次重连时被调用 - - :参数: - - * ``setup: Union[WebSocketSetup, Callable[[], Awaitable[WebSocketSetup]]]`` - """ - self.websockets.append(setup) - @overrides(ReverseDriver) def run( self, @@ -273,18 +240,6 @@ class Driver(ReverseDriver, ForwardDriver): **kwargs, ) - def _run_forward(self): - for setup in self.http_pollings: - self.connections.append(asyncio.create_task(self._http_loop(setup))) - for setup in self.websockets: - self.connections.append(asyncio.create_task(self._ws_loop(setup))) - - def _shutdown_forward(self): - self.shutdown.set() - for task in self.connections: - if not task.done(): - task.cancel() - async def _handle_http(self, adapter: str, request: Request): data = await request.body() @@ -386,6 +341,73 @@ class Driver(ReverseDriver, ForwardDriver): finally: self._bot_disconnect(bot) + +class FullDriver(ForwardDriver, Driver): + """ + 完整的 FastAPI 驱动框架,包含正向 Client 支持和反向 Server 支持。 + + :使用方法: + + .. code-block:: dotenv + + DRIVER=nonebot.drivers.fastapi:FullDriver + """ + + def __init__(self, env: Env, config: NoneBotConfig): + super(FullDriver, self).__init__(env, config) + + self.http_pollings: List[HTTPPOLLING_SETUP] = [] + self.websockets: List[WEBSOCKET_SETUP] = [] + self.shutdown: asyncio.Event = asyncio.Event() + self.connections: List[asyncio.Task] = [] + + self.on_startup(self._run_forward) + self.on_shutdown(self._shutdown_forward) + + @property + @overrides(ForwardDriver) + def type(self) -> str: + """驱动名称: ``fastapi_full``""" + return "fastapi_full" + + @overrides(ForwardDriver) + def setup_http_polling(self, setup: HTTPPOLLING_SETUP) -> None: + """ + :说明: + + 注册一个 HTTP 轮询连接,如果传入一个函数,则该函数会在每次连接时被调用 + + :参数: + + * ``setup: Union[HTTPPollingSetup, Callable[[], Awaitable[HTTPPollingSetup]]]`` + """ + self.http_pollings.append(setup) + + @overrides(ForwardDriver) + def setup_websocket(self, setup: WEBSOCKET_SETUP) -> None: + """ + :说明: + + 注册一个 WebSocket 连接,如果传入一个函数,则该函数会在每次重连时被调用 + + :参数: + + * ``setup: Union[WebSocketSetup, Callable[[], Awaitable[WebSocketSetup]]]`` + """ + self.websockets.append(setup) + + def _run_forward(self): + for setup in self.http_pollings: + self.connections.append(asyncio.create_task(self._http_loop(setup))) + for setup in self.websockets: + self.connections.append(asyncio.create_task(self._ws_loop(setup))) + + def _shutdown_forward(self): + self.shutdown.set() + for task in self.connections: + if not task.done(): + task.cancel() + async def _http_loop(self, setup: HTTPPOLLING_SETUP): async def _build_request(setup: HTTPPollingSetup) -> Optional[HTTPRequest]: url = httpx.URL(setup.url) diff --git a/tests/.env.dev b/tests/.env.dev index d0aa5fd9..c55b1a3a 100644 --- a/tests/.env.dev +++ b/tests/.env.dev @@ -1,4 +1,4 @@ -DRIVER=nonebot.drivers.fastapi:Driver +DRIVER=nonebot.drivers.fastapi:FullDriver HOST=0.0.0.0 PORT=2333 DEBUG=true