mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-16 22:51:11 +00:00
* feat: 支持 v2 插件、原生扩展与签名发布 * fix: 修复测试 * feat: 增强宿主 SDK、运行观测与制品维护能力 * feat: 增强文件传输、配置观测与本地开发能力 * feat: 支持 SSE 实时事件流并完善开发脚手架 * feat: 完善长连接鉴权复核与关闭回收 * feat: 增强生命周期与任务关闭可靠性 * feat: 收紧健康检查契约并补齐前端与真实网络验收 * feat: 增加SDK溯源与离线更新工具并验证跨版本兼容 * feat: 增加持久化业务示例与受控 Python 交付 * feat: 增加统一运行诊断与多worker状态观测 * feat: 增加固定目标发布等待与自动验收 * fix: 修复多环境插件部署前缀与代理配置不一致 * fix: 修复测试
77 lines
3.2 KiB
Python
77 lines
3.2 KiB
Python
import asyncio
|
|
import inspect
|
|
from collections.abc import Callable, Mapping, Sequence
|
|
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
from fastapi import APIRouter
|
|
from starlette.types import ASGIApp
|
|
|
|
from plugins.core.sdk.context import PluginHostContext
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PluginDefinition:
|
|
"""
|
|
入口返回值;构造时不打开连接、不执行迁移。
|
|
|
|
原生扩展通过 PyO3 导入这个类并创建实例即可,无需继承 Python 基类。
|
|
生命周期 Hook 继续在清单中声明,避免安装命令和请求 worker 得到不同的能力清单。
|
|
|
|
:param api_version: 插件能力对象协议版本
|
|
:param routers: Router 接入方式显式提供的路由集合
|
|
:param app_factory: ASGI 接入方式创建子应用的同步工厂
|
|
:param register_models: 同步注册 ORM 元数据的可选回调
|
|
"""
|
|
|
|
api_version: int = 1
|
|
routers: Sequence[APIRouter] = field(default_factory=tuple)
|
|
app_factory: Callable[[PluginHostContext], ASGIApp] | None = None
|
|
register_models: Callable[[PluginHostContext], None] | None = None
|
|
|
|
def validate(self, integration: str) -> None:
|
|
"""
|
|
导入后验证对象协议,不依赖 Rust 函数的反射签名。
|
|
|
|
:param integration: 清单声明的 Web 接入方式
|
|
:return: None
|
|
"""
|
|
if type(self.api_version) is not int or self.api_version != 1:
|
|
raise ValueError(f'不支持的 PluginDefinition API 版本:{self.api_version}')
|
|
if any(not isinstance(router, APIRouter) for router in self.routers):
|
|
raise TypeError('PluginDefinition.routers 必须包含 APIRouter 实例')
|
|
if integration == 'asgi':
|
|
if not callable(self.app_factory) or self.routers:
|
|
raise ValueError('ASGI 插件必须提供 app_factory,且不能同时返回 routers')
|
|
elif integration == 'router':
|
|
if self.app_factory is not None:
|
|
raise ValueError('Router 插件不能返回 app_factory')
|
|
else:
|
|
raise ValueError(f'不支持的插件接入方式:{integration}')
|
|
if self.register_models is not None and not callable(self.register_models):
|
|
raise TypeError('register_models 必须可调用')
|
|
|
|
|
|
async def await_plugin_callback(
|
|
callback: Callable[..., Any],
|
|
*args: Any,
|
|
timeout: float = 30.0,
|
|
kwargs: Mapping[str, Any] | None = None,
|
|
) -> Any:
|
|
"""
|
|
等待 Python 或原生 awaitable;同步入口必须立即返回。
|
|
|
|
超时只能取消异步等待,不能强制终止阻塞原生函数。平台不在线程池中执行
|
|
生命周期写操作,也不将同步返回值视为成功,以免事务结束后继续产生副作用。
|
|
|
|
:param callback: 必须立即返回可等待对象的插件回调
|
|
:param args: 传给回调的位置参数
|
|
:param timeout: 异步等待超时时间,单位为秒
|
|
:param kwargs: 传给回调的关键字参数
|
|
:return: 等待插件回调完成后的返回值
|
|
"""
|
|
result = callback(*args, **(kwargs or {}))
|
|
if not inspect.isawaitable(result):
|
|
raise TypeError('v2 插件异步回调必须立即返回 awaitable')
|
|
return await asyncio.wait_for(result, timeout=timeout)
|