首页/新闻资讯/正文详情

Ajenti 插件开发指南:通过 HttpPlugin 与 @endpoint 构建 HTTP 处理接口

发布时间:2026/9/26 15:56:21 来源:云帆数科 栏目:资讯中心
Ajenti 插件开发指南:通过 HttpPlugin 与 @endpoint 构建 HTTP 处理接口
后端运维【免费下载链接】ajentiAjenti Core and stock plugins项目地址https://gitcode.com/gh_mirrors/aj/ajenti点击查看免费下载导读本文围绕 docs/source/dev/http.rst 的开发者文档展开系统讲解 Ajenti 插件如何注册并处理 HTTP 请求从继承HttpPlugin抽象接口、使用get/post等路由装饰器到用endpoint开启 JSON API 模式或底层页面模式再到HttpContext提供的完整响应控制能力。读完本文你将能够为 Ajenti 编写出可被前端直接调用的 REST 风格 API 端点并理解请求从 WSGI 进入后经 master/worker 架构最终派发到插件处理器的完整链路。一、Ajenti 的 HTTP 请求处理架构概览Ajenti 采用 master/worker 的多进程架构主进程master负责会话管理与请求接收每个登录会话由独立的 worker 子进程承载参见 aj/gate/gate.py 中WorkerGate对 gipc 管道与子进程的封装。一次 HTTP 请求的生命周期大致如下WSGI 请求进入HttpRoot被包装为HttpContextaj/http.pyGateMiddleware依据 Cookie 会话或 HTTP Basic 认证找到或新建对应 worker将序列化后的HttpContext通过管道发送过去aj/gate/middleware.pyworker 进程内的Worker.handle_http_request反序列化上下文交给AuthenticationMiddleware与CentralDispatcher组成的中件栈aj/gate/worker.pyCentralDispatcher遍历所有已注册的HttpPlugin实例命中路由则执行对应处理函数并返回结果aj/routing.py。因此插件的 HTTP 能力本质上就是向HttpPlugin这一接口注册组件。理解这条链路有助于定位为什么我的端点没被调用之类的问题路由匹配、方法匹配与认证检查都发生在 worker 进程内。二、定义 HTTP 端点HttpPlugin 接口与路由装饰器2.1 继承 HttpPlugin插件通过扩展aj.api.http.HttpPlugin抽象类来提供自己的 HTTP 端点并用jadi的component机制注册例如from jadi import component from aj.api.http import get, HttpPlugin component(HttpPlugin) class Handler(HttpPlugin): def __init__(self, context): self.context context get(r/api/demo4/calculate/(?Poperation\w)/(?Pa\d)/(?Pb\d)) def handle_api_calculate(self, http_context, operationNone, aNone, bNone): http_context.respond_ok() return Hello!HttpPlugin在 aj/api/http.py 中定义其handle(http_context)方法会遍历类字典中带有url_pattern属性的方法用编译后的正则匹配http_context.path命中后将命名捕获组作为关键字参数传入处理函数。__init__(self, context)中保存的context携带身份信息context.identity、worker 引用等运行时数据。2.2 请求方法装饰器get、post、delete、head、put、patchaj.api.http通过requests_decorator_generator动态生成了完整的 HTTP 方法装饰器aj/api/http.py标准 HTTP 方法get、post、delete、head、put、patchWebDAV 方法propfind、mkcol、options、proppatch、copy、move、lock、unlockAjenti 的文件管理、WebDAV 相关功能即依赖这些方法。用法统一为get(r/api/foo/(?Pid\d)) def handle_foo(self, http_context, idNone): ...装饰器接收一个 URL 正则pattern^与$是隐式添加的即整个路径必须完全匹配参见 aj/api/http.py 中re.compile(f^{pattern}$)。正则中的命名捕获组(?Pname...)会在匹配后作为**kwargs注入处理函数。方法匹配由HttpPlugin.handle内部的check_method完成aj/api/http.py规则如下处理函数标注的 method 与http_context.method取自REQUEST_METHOD统一转为大写一致才可调用HEAD 请求被允许打在 GET 目标上以兼容健康检查等场景处理函数返回值若为str会被编码为 UTF-8 字节若为生成器types.GeneratorType如流式文件下载则原样透传aj/api/http.py。2.3 旧式 url 装饰器的兼容代码库中还存在较早的url(pattern)装饰器aj/api/http.py它只绑定url_pattern而不绑定 method。HttpPlugin.handle在检测到方法上没有method属性时会回退到旧式兼容路径并输出日志警告Backward url compatibility ...。新代码应一律使用get/post等按方法区分的装饰器。三、endpointAPI 模式与页面模式原文档强调建议给所有 HTTP 处理方法都加上endpoint装饰器。endpoint(pageFalse, apiFalse, authTrue)定义在 aj/api/endpoint.py三个参数含义如下参数默认值作用authTrue要求已认证会话否则返回401 UnauthenticatedapiFalse将响应与异常自动包装为 JSON并特殊处理EndpointErrorpageFalse启用页面模式提供对 HTTP 响应的底层控制3.1 endpoint(apiTrue)自动 JSON 编码import time from jadi import component from aj.api.http import get, HttpPlugin from aj.api.endpoint import endpoint, EndpointError, EndpointReturn component(HttpPlugin) class Handler(HttpPlugin): def __init__(self, context): self.context context get(r/api/demo4/calculate/(?Poperation\w)/(?Pa\d)/(?Pb\d)) endpoint(apiTrue) def handle_api_calculate(self, http_context, operationNone, aNone, bNone): start_time time.time() try: if operation add: result int(a) int(b) elif operation divide: result int(a) / int(b) else: raise EndpointReturn(404) except ZeroDivisionError: raise EndpointError(Division by zero) return { value: result, time: time.time() - start_time }这是原文档给出的完整示例。在apiTrue模式下aj/api/endpoint.py处理函数的返回值dict、list 等会经simplejson.dumps序列化为 JSON自动写入Content-Type: application/json响应头异常按类型转换为对应 HTTP 状态码与 JSON 错误体详见下文第四节。3.2 endpoint(pageTrue)底层响应控制当你需要完全控制响应头、返回非 JSON 内容如 HTML、XML、文件流时使用pageTrueget(r/api/test) endpoint(pageTrue) def handle_api_calculate(self, http_context): http_context.add_header(Content-Type, ...) content Hello! # return http_context.respond_not_found() # return http_context.respond_forbidden() # return http_context.file(/some/path) http_context.respond_ok() return content在页面模式下endpoint不会自动序列化返回值也不会把异常转成 JSONEndpointError、SecurityError与其他异常都会直接向上抛出aj/api/endpoint.py由CentralDispatcher捕获并渲染错误页。处理函数负责自己调用http_context的响应方法见第五节。注意endpoint是包裹在路由装饰器外层的装饰顺序为上例所示即先get标记路由再endpoint包装执行逻辑二者缺一不可。四、异常与状态码的约定EndpointError、EndpointReturn、SecurityErrorendpoint的异常处理逻辑定义了 Ajenti API 的错误语义aj/api/endpoint.pyEndpointReturn(code)主动返回指定 HTTP 状态码可在响应体中附带data。例如上述计算 API 中对未知操作raise EndpointReturn(404)。它的语义是可预见的业务性返回不会触发客户端崩溃对话框EndpointError(message)表示可预见的错误如除零、参数非法。在apiTrue模式下转为500状态码并返回包含message、exception类名与traceback的 JSON 对象aj/api/endpoint.pySecurityError权限不足时抛出apiTrue模式下转为403 Forbiddenaj/api/endpoint.py。SecurityError定义于 aj/auth.py其 message 形如Forbidden: permission ... is required未捕获的普通异常在apiTrue模式下同样转为500并返回带 traceback 的 JSON便于前端排查在pageTrue模式下则重新抛出交给上层。另外若处理函数内部已通过http_context.respond(404 Not Found)等方式设置过状态endpoint会检测context.status中不含200的情况并加以传播aj/api/endpoint.py。五、HttpContext请求数据与响应控制每个处理函数接收的第一个参数都是HttpContext实例aj/http.py。它的主要属性包括属性说明envWSGI 环境字典pathURL 路径段method请求方法大写headers响应头列表键值对元组body请求体字节串query合并后的查询参数与表单参数response_ready是否已提交过响应5.1 读取请求数据查询字符串与表单HttpContext.__init__会同时解析 URL 查询串cgi.FieldStorage与application/x-www-form-urlencoded、multipart/form-data表单体CGIFieldStorage合并到query字典中aj/http.pyJSON 请求体http_context.json_body()直接对self.body做 UTF-8 解码与json.loadsaj/http.py。plugins/check_certificates/views.py 中的真实插件就是通过http_context.json_body()[url]读取 POST 载荷的。5.2 响应方法速查原文档提示参见aj.http.HttpContext获取可用的http_context方法以下是从 aj/http.py 提取的完整响应工具集方法效果respond(status)以任意状态行创建响应response_ready Truerespond_ok()200 OKrespond_server_error()500 Server Error返回[bServer Error]respond_unauthenticated()401 Unauthenticatedrespond_forbidden()403 Forbiddenrespond_not_found()404 Not Foundrespond_bad_request()400 Bad Requestredirect(location)302 Found并写入Location头add_header(key, value)追加响应头remove_header(key)移除指定响应头gzip(content, compression6)返回 gzip 压缩响应自动设置Content-Encoding与Content-Lengthfile(path, streamFalse, inlineFalse, nameNone)返回文件内容响应见 5.3run_response()最终调用 WSGIstart_response()补齐X-Frame-Options: SAMEORIGIN与 CSP 安全头5.3 file()内置的静态文件服务HttpContext.file()是页面模式下最实用的方法之一它已经处理了完整 HTTP 语义aj/http.py路径穿越防护路径含..直接返回 403MIME 类型映射.html、.css、.js、.png、.jpg、.svg、.woff、.pdf均有对应Content-Type其余回落为application/octet-stream条件请求支持If-Modified-Since返回304 Not Modified支持Range返回206 Partial Content下载语义inlineTrue时为内联展示否则为attachment下载并支持自定义filename流式读取streamTrue时以 100 KB 缓冲块配合gevent.sleep(0)让步逐块产出适合大文件。六、从源码看真实插件的 HTTP 端点写法6.1 证书检查插件post JSON 请求体plugins/check_certificates/views.py 展示了 POST 端点的标准范式component(HttpPlugin) class Handler(HttpPlugin): def __init__(self, context): self.context context post(r/api/check_cert) endpoint(apiTrue) def handle_api_check_cert(self, http_context): url http_context.json_body()[url] return json.loads(json.dumps(checkOnDom(*url.split(:))))6.2 Augeas 插件URL 参数 EndpointReturnplugins/augeas/views.py 演示了命名捕获组与业务性 404 的组合get(r/api/augeas/endpoint/(?Pid.)) endpoint(apiTrue) def handle_api_get(self, http_context, idNone): ep self.__get_augeas_endpoint(id) if not ep: raise EndpointReturn(404) aug ep.get_augeas() ...此外plugins/core/views/api.py 中集中体现了完整的方法矩阵get(/api/core/identity)、post(/api/core/auth)、delete(/api/core/totps/(?Ptimestamp\d*))等可作为编写 CRUD 风格端点的参考范本。七、请求处理流程与路由解析的源码级印证理解以下细节有助于调试端点不生效的问题Worker 内建处理器栈Worker.__init__构建了HttpMiddlewareAggregator([AuthenticationMiddleware, CentralDispatcher])aj/gate/worker.py并在每个请求到来时再叠加所有HttpMiddleware组件aj/gate/worker.py认证检查AuthenticationMiddleware.handle会处理 SSL 客户端证书并写入X-Auth-Identity头aj/auth.pyendpoint(authTrue)默认在context.identity为空时直接返回 401中央派发CentralDispatcher.handle遍历HttpPlugin.all(self.context)的所有实例依次调用instance.handle(http_context)谁返回非None输出就用谁的结果全部未命中则落入InvalidRouteHandler渲染 404 页面aj/routing.py。路由的^...$全匹配语义也意味着若你的正则写成了不带锚点的前缀匹配路径就不会命中worker 超时master 等待 worker 响应的默认超时为 600 秒超时返回504 Gateway Timeoutaj/gate/middleware.py因此长时间运行的任务不应阻塞在 HTTP 处理函数内。结语Ajenti 的 HTTP 处理模型非常简洁HttpPlugin负责把类方法映射为URL 路由endpoint负责把普通函数升级为带认证、带 JSON 编码、带错误约定的标准端点HttpContext则提供了构建任意响应文件、压缩流、重定向、自定义状态码的全部底层能力。掌握这三层抽象再对照 plugins/core/views/api.py 等仓库内真实插件的写法即可为 Ajenti 快速添加稳定的 API 端点。赞分享后端运维【免费下载链接】ajentiAjenti Core and stock plugins项目地址https://gitcode.com/gh_mirrors/aj/ajenti点击查看免费下载相关推荐Ajenti插件开发入门指南从零开始构建你的第一个管理面板插件Ajenti插件开发入门指南从零开始构建你的第一个管理面板插件 前言 Ajenti是一个功能强大的服务器管理面板框架它允许开发者通过插件扩展其功能。本文将带后端运维Envoy HTTP Cache Filter 存储插件开发指南深入理解 HttpCache、LookupContext 与 InsertContext 接口Envoy HTTP Cache Filter 存储插件开发指南深入理解 HttpCache、LookupContext 与 InsertContext 接口云原生服务网格网络微服务Telegraf ifname 处理器插件实战通过 SNMP 将接口编号解析为接口名称Telegraf ifname 处理器插件实战通过 SNMP 将接口编号解析为接口名称 导读 ifname 是 Telegraf 内置的流式处理器Strea可观测性指标监控运维创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

基于sklearn的中文文本挖掘完整流程与避坑指南
基于sklearn的中文文本挖掘完整流程与避坑指南

简介:一套围绕Python与sklearn库展开的文本挖掘实践资源,特别适合需要系统学习文本预处理、特征工程与建模流程的数据分析初学者和相关专业开发者。资源以一百份文本文件为对象,完整演示了分词处理、去除停用词、词干提取、词形还原等步骤&am… · 2026/9/26 15:56:08

GPT-6与Claude 5.0实战解析:大模型微调、本地部署与Agent落地指南
GPT-6与Claude 5.0实战解析:大模型微调、本地部署与Agent落地指南

1. 这周AI圈到底发生了什么上周三凌晨两点,我还在调一个7B模型的微调脚本,群里突然炸了——有人甩出一张截图,说GPT-6的灰度测试入口已经出现在部分企业账号里,紧接着Claude 5.0的API文档也在开发者社区被扒了出来。那一夜我几乎没… · 2026/9/26 15:56:02

Xshell 6 提示“要继续使用此程序,您必须应用最新的更新或使用新版本”:用 TaoToken 统一 Key 通道整理配置与验证流程
Xshell 6 提示“要继续使用此程序,您必须应用最新的更新或使用新版本”:用 TaoToken 统一 Key 通道整理配置与验证流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 15:55:56

硅基流动实测复盘:开源模型MaaS与全模型聚合平台的搭配策略
硅基流动实测复盘:开源模型MaaS与全模型聚合平台的搭配策略

硅基流动作为国产MaaS第一梯队的代表,综合口碑扎实:150余款模型覆盖语言、图像、视频、语音,注册用户规模庞大,自研推理引擎宣称语言推理提速明显,注册即送体验额度,十分钟就能调通首个API。实测下来,它的开源模型生态与价格确实是强项,但闭源模型缺席也让它的适用边界清晰。本… · 2026/9/26 16:26:41

Agent Teams / Swarms 实战:用 Claude Code Subagents 搭一套可复用的智能体协作骨架
Agent Teams / Swarms 实战:用 Claude Code Subagents 搭一套可复用的智能体协作骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:26:41

E2-10G网络测试模块:全速率、超线速与深协议解析技术解析
E2-10G网络测试模块:全速率、超线速与深协议解析技术解析

1. 这块“E2-10G”到底在解决什么真问题?“全速率超线速深协议”——这九个字不是宣传稿里的空洞口号,而是我过去三年在数据中心网络测试现场反复摔打出来的痛点清单。去年底给一家头部云厂商做400G交换机压力验证时,我们卡在了一个极其尴尬的… · 2026/9/26 16:26:35

Cursor 使用教程:从安装、订阅到高级技巧,附 TaoToken 统一 Key 配置
Cursor 使用教程:从安装、订阅到高级技巧,附 TaoToken 统一 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:26:35

cursor打开文本中文乱码解决方法:settings.json 配 TaoToken 统一 Key 通道
cursor打开文本中文乱码解决方法:settings.json 配 TaoToken 统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:26:35

统计信息搜集加SQL硬编码导致library cache lock 和cursor pin wait on x:TaoToken统一Key通道下的诊断配置与验证
统计信息搜集加SQL硬编码导致library cache lock 和cursor pin wait on x:TaoToken统一Key通道下的诊断配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:26:29

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码