ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Tyk Coprocess Python 插件开发指南:用 Python 编写 API 网关中间件与事件处理器

Tyk Coprocess Python 插件开发指南:用 Python 编写 API 网关中间件与事件处理器 API网关后端云原生【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址https://gitcode.com/gh_mirrors/ty/tyk点击查看免费下载Tyk Coprocess 是一套允许开发者用 Python 等语言编写网关插件的机制本文以仓库中的 coprocess/python/README.md 为主体结合源码与测试系统讲解如何在 Tyk 中启用 Python 支持、编写自定义中间件与认证钩子、注册事件处理器以及 Cython 绑定背后的构建原理。读完本文你将掌握go build -tags coprocess python的完整构建流程、custom_middleware配置规范、装饰器钩子模型以及如何利用 Coprocess Gateway API 读写 Redis 数据。一、Coprocess 与 Python 支持架构定位Tyk 的 CoprocessCo-process特性允许在网关进程内直接执行外部语言编写的中间件逻辑无需独立的微服务或远程调用。Python 绑定是其中最常用的实现之一当前绑定支持Python 3.x。本 README 的定位是提供架构概览与实现说明而完整的中文实战教程可以在 coprocess/README.md 与仓库内各类示例文件中找到对应实现。从源码结构看Python 插件相关代码集中在coprocess/python目录dispatcher.pyPython 侧的分发器负责按bundle_hash与钩子名查找并执行中间件、分发事件binding.h声明了Python_Init、Python_LoadDispatcher、Python_NewDispatcher、Python_DispatchHook、Python_DispatchEvent等 C 接口作为 Go 与 Python 解释器之间的桥接层tyk/Python 侧的工具包包含装饰器、请求/会话包装器、Gateway API 绑定等。构建时需要显式启用coprocess与python两个 build tag否则相关 C 绑定代码会被 Go 编译器忽略。二、构建要求与启用方式2.1 依赖清单根据 README构建带 Python 支持的 Tyk 需要以下环境依赖说明Python 3.x运行时解释器插件实际执行的宿主GoTyk 主程序的编译工具链Cython仅在需要修改并重新编译 Gateway API 绑定时才必需protobufPython 模块安装方式pip3 install protobuf3.20.2grpcgRPC 模块安装方式pip3 install grpcioprotobuf 与 grpcio 用于提供 coprocess 各消息结构如coprocess_object_pb2、coprocess_session_state_pb2以及 gRPC 相关支持仓库 coprocess/python/proto/ 下已经生成了对应的*_pb2.py文件供 Python 侧导入。2.2 构建命令启用 Coprocess Python 支持的标准构建命令是go build -tags coprocess python注意不带这两个 build tag 的普通构建会忽略 C 绑定文件这正是cythonize脚本在生成代码中打补丁的原因详见下文构建细节。三、编写自定义 Python 中间件3.1 在 API 定义中声明中间件自定义中间件需要在 API 定义文件的custom_middleware字段下声明完整示例可参考 apps/coprocess_app_sample.jsoncustom_middleware: { pre: [ { name: MyPreMiddleware, require_session: false } ], post: [ { name: MyPostMiddleware, require_session: false } ], driver: python }字段含义pre请求进入网关后、任何认证发生之前执行的钩子列表post认证完成后执行的钩子列表此时可以访问session对象namePython 函数的函数名必须与 Python 源码中的函数名一致require_session是否要求会话对象存在false表示钩子不强依赖会话driver插件驱动类型Python 插件必须为python。当钩子类型为 Pre、Post 或 PostAuthCheck 时可以链式串联多个钩子函数Tyk 会按声明顺序依次执行。3.2 Python 中间件实现Tyk 会加载middleware/python目录下的所有模块仓库 middleware/python/。与上述定义匹配的 Python 中间件写法如下from tyk.decorators import * Pre def MyPreMiddleware(request, session, spec): print(my_middleware: MyPreMiddleware) return request, session Post def MyPreMiddleware(request, session, spec): print(my_middleware: MyPreMiddleware) return request, session注意装饰器来自tyk.decorators包函数签名固定为(request, session, spec)且必须原样返回request, session否则请求链路的后续处理会丢失对象。3.3 装饰器钩子模型与参数自适应从源码 coprocess/python/tyk/decorators.py 可以看到完整的装饰器集合Pre认证前执行Post认证后执行可访问会话PostKeyAuth密钥认证后执行CustomKeyCheck自定义认证检查4 参签名(request, session, metadata, spec)Event事件处理器2 参签名(event, spec)Hook通用钩子包装类。其中Hook类通过inspect.getfullargspec计算参数个数按 3/4/5 个参数自适应分发调用decorators.py#L13-L25这解释了为什么不同钩子类型可以有不同的函数签名。对应地tyk/middleware.py 中的process方法根据arg_count决定调用方式3 参返回(request, session)4 参额外处理metadata5 参Response 钩子返回(request, response, session, md, spec)。3.4 请求与 Session 包装对象为了以 Python 惯用方式操作请求tyk包提供了快速包装器coprocess/python/tyk/request.pyTykCoProcessRequest封装了add_header、delete_header、add_param、delete_param、get_header等方法coprocess/python/tyk/session.pyTykSession直接映射自coprocess_session_state_pb2.SessionState同时导出AccessSpec、AccessDefinition、BasicAuthData、JWTData、Monitor等 protobuf 类型。例如在 Pre 钩子中修改请求头from tyk.decorators import * Pre def AppendHeader(request, session, spec): request.add_header(custom_header, custom_value) return request, session四、用 Python 实现 API 认证README 将用 Python 认证 API指向了官方认证教程仓库中的受保护 API 示例 apps/coprocess_app_sample_protected.json 展示了认证型 API 的关键配置{ use_keyless: false, enable_coprocess_auth: true, custom_middleware: { auth_check: { name: MyAuthCheck }, driver: python } }关键点use_keyless: false关闭无密钥访问enable_coprocess_auth: true启用 Coprocess 认证认证逻辑完全交由 Python 钩子完成custom_middleware.auth_check.name指定认证检查钩子的函数名。认证钩子的完整签名来自CustomKeyCheck装饰器为(request, session, metadata, spec)。仓库测试 coprocess/python/coprocess_python_test.go 中的pythonBundleWithAuthCheck给出了一个可运行的认证实现coprocess_python_test.go#L29-L48from tyk.decorators import * from gateway import TykGateway as tyk Hook def MyAuthHook(request, session, metadata, spec): auth_header request.get_header(Authorization) if auth_header valid_token: session.rate 1000.0 session.per 1.0 session.max_query_depth 1 session.quota_max 1 session.quota_renewal_rate 60 metadata[token] valid_token if auth_header token_without_quota: policy_id request.get_header(Policy) session.apply_policy_id policy_id metadata[token] token_without_quota return request, session, metadata可以看到认证钩子中可以直接为会话设置速率限制session.rate、session.per、配额session.quota_max、session.quota_renewal_rate以及应用策略session.apply_policy_id并将认证信息写入metadata。同一测试文件中的用例验证了认证成功返回 200、无效 token 返回 403 的完整行为coprocess_python_test.go#L243-L282这是理解认证钩子语义的最直接证据。五、用 Python 编写事件处理器除了请求中间件Tyk 还允许用 Python 编写事件监听器。5.1 在 API 定义中注册事件处理器第一步是在 API 定义中配置event_handlers见 apps/coprocess_app_sample_protected.jsonevent_handlers: { events: { AuthFailure: [ { handler_name: cp_dynamic_handler, handler_meta: { name: my_handler } } ] } }上述配置为AuthFailure每次认证失败时触发事件注册了一个处理器handler_name必须是cp_dynamic_handlerhandler_meta.name指向 Python 函数名该函数写在event_handlers中见 event_handlers/my_handler.pyfrom tyk.decorators import Event Event def my_handler(event, spec): print(-- my_handler:) print( Event:, event) print( Spec:, spec)5.2 事件对象的结构事件触发时Tyk 会向该函数传入一个形如下面的 Python 对象{ TimeStamp: 2016-08-19 11:13:31.537047694 -0400 PYT, Meta:{ Path:/coprocess-auth-tyk-api-test/, Origin:127.0.0.1, Message:Auth Failure, OriginatingRequest:R0VUIC9jb3Byb2Nlc3MtYXV0aC10eWstYXBpLXRlc3QvIEhUVFAvMS4xDQpIb3N0OiAxMjcuMC4wLjE6ODA4MA0KVXNlci1BZ2VudDogY3VybC83LjQzLjANCkFjY2VwdDogKi8qDQpBdXRob3JpemF0aW9uOiAxDQoNCg, Key: }, Type: AuthFailure }其中OriginatingRequest是原始 HTTP 请求的 Base64 编码Meta内包含路径、来源 IP、失败消息等信息Type指明事件类型。从实现看coprocess/python/tyk/event.py 中的TykEvent通过json.loads将事件 JSON 直接灌入__dict__因此可以在处理函数中以属性方式访问event.Meta、event.Type等字段事件分发则由 dispatcher.py#L72-L79 的dispatch_event完成它根据event.spec[APIID]查找对应的钩子并执行。5.3 手动触发验证可以向受保护的 Coprocess API 发送一个带无效 Authorization 头的请求来触发上述处理器curl http://127.0.0.1:8080/coprocess-auth-tyk-api-test/ -H Authorization: invalidtoken网关日志中即可看到my_handler打印的事件与 spec 内容。六、Coprocess Gateway API 与 Redis 存储6.1 Python 绑定入口Coprocess Gateway API 的 Python 绑定采用 Cython 语法编写本质上是一个绑定文件README 中描述为gateway.pyx仓库当前实际实现为 tyk/gateway.py。该绑定通过ctypes直接调用宿主进程内导出的 C 函数如TykGetData、TykStoreData、CoProcessLog、TykTriggerEvent从而让 Python 代码访问网关能力。6.2 读写 Redis 数据绑定暴露了存储处理器允许插件读写 Redis 键from tyk.decorators import * from gateway import TykGateway as tyk Pre def SetKeyOnRequest(request, session, spec): tyk.store_data( my_key, expiring_soon, 15 ) val tyk.get_data(cool_key) return request, sessiontyk.store_data(key, value, ttl)设置带 TTL秒的键tyk.get_data(key)读取键值。除此之外绑定还提供tyk.log(message, level)/tyk.log_error(message)向网关日志输出信息见 tyk/gateway.py#L9-L18tyk.trigger_event(name, payload)从插件侧触发网关事件。这些能力让 Python 中间件可以实现自定义限流、计数、缓存等逻辑而不必绕道外部存储。七、构建细节cythonize 与 build tags7.1 重新编译 Gateway API 绑定如果修改了绑定源码需要在仓库根目录执行cd coprocess/python ./cythonize gateway该命令会对gateway.pyx执行 cythonize生成gateway.c与gateway.h。若要编译其他绑定mybinding.pyx为你的 Cython 输入文件cd coprocess/python ./cythonize mybinding7.2 为什么需要 cythonize 打补丁cythonize是一个辅助脚本作用是编译 Python 源文件并给生成结果打上本 Coprocess 特性专用的 build tags 补丁。这很重要只有这样才能保证普通构建不带 coprocess/python 标签时 Go 编译器忽略 C 绑定文件、Tyk 依然可正常编译。一个标准 Cython 绑定文件的头部原本是这样的/* Generated by Cython 0.24.1 */ /* BEGIN: Cython Metadata { distutils: { depends: [] }, module_name: gateway } END: Cython Metadata */经过cythonize处理后文件头部会被补上 build tags从而只在go build -tags coprocess python时参与编译// build coprocess // build python /* Generated by Cython 0.24.1 */ /* BEGIN: Cython Metadata { distutils: { depends: [] }, module_name: gateway } END: Cython Metadata */每次重新编译绑定后C 源码会发生变化此时需要重新构建 Tyk 二进制。7.3 绑定生命周期与 CPython C APIREADME 明确说明运行时并不直接使用.pyx文件。构建结束后绑定已成为 Tyk 二进制的一部分可从 Go 代码加载访问。绑定的初始化函数声明在 binding.h 中Python 解释器启动后需要调用Python_Init等初始化函数随后import mymodule才能生效——gateway模块及其函数正是通过这一机制暴露给 Python 的。从实现看Python 插件重度使用 CPython 的 C API这是 Python 官方提供、文档完善的 C 接口插件宿主侧通过Python_LoadDispatcher加载 dispatcher.py再经Python_DispatchHook/Python_DispatchEvent完成请求钩子与事件的分发Go 侧与 Python 侧通过 protobuf 序列化消息交换数据见 tyk/object.py 中TykCoProcessObject的ParseFromString/SerializeToString。八、内置模块与运行时约定标准库全部可用所有 Python 标准模块均可直接导入可安装第三方模块通过 pip 安装到本地 Python 环境后即可加载额外模块无需 cffiREADME 指出采用 Cython cgo 的方式替代了 cffi——cffi 需要在 setup 阶段先安装模块而当前方案把绑定直接编进二进制简化了部署。从 coprocess/python/tyk/middleware.py 的加载逻辑看插件以bundle为单位管理TykMiddleware解析manifest.json中的file_list单文件 bundle 则直接加载该文件通过register_handlers扫描模块内所有被装饰器包装的可调用对象并登记为钩子dispatcher.py 的TykDispatcher则维护bundles与hook_table按bundle_hash与钩子名执行查找和分发。九、如何验证与运行仓库为 Python 插件提供了完整的集成测试入口 coprocess/python/coprocess_python_test.go其setupGateway以EnableCoProcess: true和PythonPathPrefix启动测试网关覆盖了带认证钩子的单文件 bundle有效/无效 token 分别返回 200/403认证钩子应用策略apply_policy_id后的配额行为Post 钩子对会话元数据的访问Response 钩子对响应对象的处理ID 提取器见 coprocess_id_extractor_python_test.go。这些测试既是插件 API 的活文档也可作为你编写自定义 Python 中间件时的行为参照。结语Tyk 的 Coprocess Python 支持本质上是Go 网关 进程内 Python 解释器 protobuf 消息桥接的插件体系通过custom_middleware声明钩子、用装饰器标记执行时机、借助 Gateway API 读写 Redis 与日志再配合cythonize与 build tags 把绑定编进二进制。无论是请求预处理、自定义认证、响应改写还是事件监听都可以用一份 Python 文件在网关内部完成且整个过程不需要部署任何外部服务。延伸阅读仓库内coprocess/README.mdCoprocess 总体架构说明apps/coprocess_app_sample.json 与 apps/coprocess_app_sample_protected.json普通中间件与认证型 API 的完整配置示例event_handlers/my_handler.pyPython 事件处理器示例middleware/python/网关默认加载的 Python 中间件目录coprocess/python/coprocess_python_test.goPython 插件端到端集成测试coprocess/python/proto/Python 侧使用的 protobuf 消息定义。赞分享API网关后端云原生【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址https://gitcode.com/gh_mirrors/ty/tyk点击查看免费下载相关推荐Tyk Coprocess 插件框架实战使用 Python、Lua 与 gRPC 编写自定义 API 中间件Tyk Coprocess 插件框架实战使用 Python、Lua 与 gRPC 编写自定义 API 中间件 CoprocessCo Process是 TAPI网关后端云原生Tyk Coprocess gRPC 插件开发指南用 gRPC 后端编写 API 中间件与自定义认证Tyk Coprocess gRPC 插件开发指南用 gRPC 后端编写 API 中间件与自定义认证 本文以 Tyk 开源仓库 coprocess/grpc/API网关后端云原生Tyk Gateway Python 插件镜像扩展指南在官方 Docker 镜像中启用 Python CoprocessTyk Gateway Python 插件镜像扩展指南在官方 Docker 镜像中启用 Python Coprocess 导读 自 Tyk Gateway vAPI网关后端云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表