7.5 KiB
以下是为提供的 FunctionProcessor 类编写的 Markdown 格式技术文档,适用于项目开发文档或 API 文档场景。
FunctionProcessor 技术文档
概述
FunctionProcessor 是一个基于 aiohttp 的异步请求处理器类,继承自 BaseProcessor。它用于将 HTTP 请求动态映射到通过 RegisterFunction 注册的函数上,并支持路径参数解析和运行时环境注入。该处理器特别适用于实现基于注册函数的路由分发机制。
主要功能包括:
- 解析 URL 路径中的参数
- 调用已注册的同步或异步函数
- 支持运行时命名空间(
run_ns)注入上下文变量 - 返回
Response、FileResponse或普通内容数据
导入依赖
import inspect
from appPublic.dictObject import DictObject
from appPublic.registerfunction import RegisterFunction
from appPublic.log import info, debug, warning, error, exception, critical
from aiohttp import web
from aiohttp.web_response import Response, StreamResponse
from .baseProcessor import BaseProcessor
依赖说明
| 模块 | 用途 |
|---|---|
inspect |
判断目标函数是否为协程函数 |
DictObject |
将字典转换为属性可访问的对象 |
RegisterFunction |
获取全局注册的函数 |
appPublic.log |
日志输出 |
aiohttp.web |
Web 服务核心组件 |
BaseProcessor |
基础处理器基类 |
类定义
class FunctionProcessor(BaseProcessor):
继承自 BaseProcessor,用于处理特定类型的 HTTP 请求并调用注册函数。
类方法
isMe(name)
@classmethod
def isMe(cls, name):
return False
说明
此方法用于判断当前处理器是否适用于给定名称的资源。在本实现中始终返回 False,表示此类不会自动匹配任何资源名 —— 其使用需显式配置。
⚠️ 注意:若需启用自动识别,请重写此方法以根据条件返回
True。
参数
name(str) - 资源名称
返回值
bool: 始终返回False
实例方法
__init__(path, resource, opts)
构造函数,初始化处理器实例。
def __init__(self, path, resource, opts):
self.config_opts = opts
BaseProcessor.__init__(self, path, resource)
参数
| 参数 | 类型 | 说明 |
|---|---|---|
path |
str |
请求路径模板 |
resource |
Any |
关联资源对象(未具体使用) |
opts |
dict |
配置选项,必须包含以下键:leading: 前缀路径,用于截断registerfunction: 注册函数名 |
属性设置
self.config_opts: 存储传入的配置项- 调用父类初始化逻辑
path_call(request, params={})
执行注册函数的核心方法,负责解析路径、获取函数并调用。
async def path_call(self, request, params={}):
流程说明
- 设置运行时环境(通过
set_run_env) - 提取
params_kw和实际请求路径 - 截去配置中指定的前缀(
leading),拆分剩余路径作为位置参数 - 从
RegisterFunction中获取目标函数 - 若函数未注册,记录错误日志并返回
None - 构造调用环境(排除敏感键)
- 异步或同步调用函数并返回结果
参数
| 参数 | 类型 | 说明 |
|---|---|---|
request |
aiohttp.web.Request |
当前 HTTP 请求对象 |
params |
dict |
可选参数字典,可覆盖默认路径等信息 |
返回值
- 函数调用结果(可以是
Response,str,dict, 或其他类型) - 如果函数未注册,返回
None
内部逻辑细节
路径处理
path1 = path[len(self.config_opts['leading']):]
if path1[0] == '/': path1 = path1[1:]
args = path1.split('/')
例如:
若 request.path = "/api/v1/user/123",且 leading="/api/v1",则 args = ['user', '123']
函数调用环境构建
env = {k:v for k,v in self.run_ns.items() if k not in ['params_kw', 'request']}
过滤掉 params_kw 和 request,避免重复传参冲突。
协程支持
if inspect.iscoroutinefunction(f):
return await f(request, params_kw, *args, **env)
return f(request, params_kw, *args, **env)
自动识别函数类型,确保正确调用同步或异步函数。
错误处理
if f is None:
error(f'{rfname=} is not registered, {rf.registKW=}')
return None
若函数未注册,输出调试信息并返回 None。
datahandle(request)
处理请求并生成响应内容的方法。
async def datahandle(self, request):
x = await self.path_call(request)
if isinstance(x, web.FileResponse):
self.retResponse = x
elif isinstance(x, Response):
self.retResponse = x
else:
self.content = x
功能
调用 path_call 执行业务逻辑,并根据返回值类型决定如何封装响应:
| 返回类型 | 处理方式 |
|---|---|
web.FileResponse |
直接赋值给 self.retResponse |
Response(含子类) |
赋值给 self.retResponse |
其他类型(如 str, dict 等) |
赋值给 self.content,由后续中间件或父类序列化 |
参数
request:aiohttp.web.Request对象
影响属性
self.retResponse: 成功时保存响应对象self.content: 成功时保存原始内容数据
配置要求(opts)
FunctionProcessor 必须接收如下配置项:
| 键名 | 类型 | 说明 |
|---|---|---|
leading |
str |
需要从路径中去除的前缀,如 /api/v1 |
registerfunction |
str |
在 RegisterFunction 中注册的函数名称 |
示例配置:
opts = {
"leading": "/api/v1",
"registerfunction": "my_registered_handler"
}
使用示例
注册函数示例
from appPublic.registerfunction import RegisterFunction
def my_handler(request, params, *args, **env):
return web.json_response({"args": args, "env": env})
RegisterFunction().register("my_registered_handler", my_handler)
创建处理器并处理请求
processor = FunctionProcessor("/api/v1/data/*", None, {
"leading": "/api/v1/data",
"registerfunction": "my_registered_handler"
})
# 在 aiohttp 路由中调用
async def handle_request(request):
await processor.datahandle(request)
if processor.retResponse:
return processor.retResponse
return web.json_response(processor.content)
注意事项与限制
- 函数注册必需:目标函数必须提前通过
RegisterFunction().register(name, func)注册。 - 函数签名要求:被调用函数应接受
(request, params_kw, *args, **kwargs)形式的参数。 - 路径前缀必须匹配:
leading必须准确匹配请求路径开头,否则可能导致参数解析异常。 - 非标准返回值需手动处理:若返回非
Response类型,需确保上游能正确序列化self.content。
日志输出
该类使用 appPublic.log 模块进行日志记录:
error: 函数未注册时输出详细错误信息- (其他日志级别暂未使用)
建议开启调试日志以便追踪调用过程。
总结
FunctionProcessor 提供了一种灵活的函数驱动式 Web 接口设计模式,适合微服务、插件化系统或需要动态绑定逻辑的场景。结合 RegisterFunction 机制,实现了低耦合、高扩展性的请求处理架构。
✅ 文档版本:1.0
📅 最后更新:2025-04-05