Python 带你快速上手 Apache APISIX 插件开发

 更新时间:2021年9月18日 08:06  点击:2344

前言:

熟悉 Apache APISIX 的小伙伴都知道,之前在社区中我们已经支持了 Java 和 Go 语言的 Runner,今天 Apache APISIX Python Runner 也来了,社区中的小伙伴们在开发 Apache APISIX 插件时又多了一种新选择。

Python 语言作为一个解释型的高级编程语言,它语法简洁易上手、代码可读性好 ,在跨平台 、可移植性 、开发效率上都有很好的表现,同时作为一个高级编程语言它的封装抽象程度比较高屏蔽了很多底层细节(例如:GC )让我们在开发的过程中可以更专注应用逻辑的开发。

同时作为一个有 30 年历史的老牌开发语言,它的生态以及各种模块已经非常完善,我们大部分的开发和应用场景都可以从社区中找到很成熟的模块或解决方案。

Python 其他的优点就不再一一赘述,当然它的缺点也比较明显:Python 作为一门解释性语言,相较于 C++ 和 Go 这样的编译型语言,在性能上的差距还是比较大的。

一、了解:项目架构

apache-apisix-python-runner 这个项目可以理解为 Apache APISIX Python 之间的一道桥梁,通过 Python Runner 可以把 Python 直接应用到 Apache APISIX 的插件开发中,最重要的还是希望让更多对 Apache APISIX 和 API 网关感兴趣的 Python 开发者通过这个项目,更多地了解和使用 Apache APISIX,以下为 Apache APISIX 多语言支持的架构图。

上图左边是 Apache APISIX 的工作流程,右边的 Plugin Runner 是各语言的插件运行器,本文介绍的 apisix-python-plugin-runner 就是支持 Python 语言的 Plugin Runner

Apache APISIX 中配置一个 Plugin Runner 时,Apache APISIX 会启动一个子进程运行 Plugin Runner,该子进程与 Apache APISIX 进程属于同一个用户,当我们重启或重新加载 Apache APISIX 时,Plugin Runner 也将被重启。

如果你为一个给定的路由配置了 ext-plugin-* 插件,请求命中该路由时将触发 Apache APISIX 通过 Unix Socket Plugin Runner 发起 RPC 调用。调用分为两个阶段:

  • ext-plugin-pre-req :在执行 Apache APISIX 内置插件(Lua 语言插件)之前
  • ext-plugin-post-req :在执行 Apache APISIX 内置插件(Lua 语言插件)之后

大家可以根据需要选择并配置 Plugin Runner 的执行时机。Plugin Runner 会处理 RPC 调用,在其内部创建一个模拟请求,然后运行多语言编写的插件,并将结果返回给 Apache APISIX

多语言插件的执行顺序是在 ext-plugin-* 插件配置项中定义的,像其他插件一样,它们可以被启用并在运行中重新定义。

二、安装:部署测试

基础运行环境:Apache APISIX 2.7、Python 3.6+

Apache APISIX 的安装部署可参考 Apache APISIX 官方文档:如何构建 Apache APISIX (https://github.com/apache/api...)进行部署。

1. 下载安装 Python Runner

$ git clone https://github.com/apache/apisix-python-plugin-runner.git
$ cd apisix-python-plugin-runner
$ make install

2. 配置 Python Runner

  • 开发模式配置

运行 Python Runner:

    $ cd /path/to/apisix-python-plugin-runner
    $ APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock python3 apisix/main.py start
    修改 Apache APISIX 配置文件
    $ vim /path/to/apisix/conf/config.yaml
    apisix:
      admin_key:
        - name: "admin"
          key: edd1c9f034335f136f87ad84b625c8f1
          role: admin
    ext-plugin:
      path_for_test: /tmp/runner.sock
    
    
    

  • 生产模式配置

修改 Apache APISIX 配置文件

    $ vim /path/to/apisix/conf/config.yaml
    apisix:
      admin_key:
        - name: "admin"
          key: edd1c9f034335f136f87ad84b625c8f1
          role: admin
    ext-plugin:
      cmd: [ "python3", "/path/to/apisix-python-plugin-runner/apisix/main.py", "start" ]
    
    
    

  • Python Runner 配置(可选)

如果需要对 Log Level Unix Domain Socket 环境变量调整可以修改 Runner 的配置文件

$ vim /path/to/apisix-python-plugin-runner/apisix/config.yaml
socket:
  file: $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path

logging:
  level: debug # error warn info debug

3. 启动 Python Runner

$ cd /path/to/apisix
# Start or Restart
$ ./bin/apisix [ start | restart ]


启动或重启 Apache APISIX 即可,此时 Apache APISIX Python Runner 已经完成配置并启动。

4. 测试 Python Runner

配置 Apache APISIX 路由及插件信息:

# 使用默认demo插件进行测试
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
  "uri": "/get",
  "plugins": {
    "ext-plugin-pre-req": {
      "conf": [
        { "name": "stop", "value":"{\"body\":\"hello\"}"}
      ]
    }
  },
  "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'


  • plugins.ext-plugin-pre-req.confRunner 插件配置,conf 为数组格式可以同时设置多个插件。
  • 插件配置对象中 name 为插件名称,该名称需要与插件代码文件和对象名称一致。
  • 插件配置对象中 value 为插件配置,可以为 JSON 字符串。

 访问验证:

$ curl http://127.0.0.1:9080/get -i
HTTP/1.1 200 OK
Date: Fri, 13 Aug 2021 13:39:18 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
host: 127.0.0.1:9080
accept: */*
user-agent: curl/7.64.1
X-Resp-A6-Runner: Python
Server: APISIX/2.7

Hello, Python Runner of APISIX

三、实践:插件开发

1. 插件目录

/path/to/apisix-python-plugin-runner/apisix/plugins


此目录中的 .py 文件将会被自动加载。

2. 插件示例

/path/to/apisix-python-plugin-runner/apisix/plugins/stop.py
/path/to/apisix-python-plugin-runner/apisix/plugins/rewrite.py

3. 插件格式

from apisix.runner.plugin.base import Base
from apisix.runner.http.request import Request
from apisix.runner.http.response import Response


class Stop(Base):
    def __init__(self):
        """
        Example of `stop` type plugin, features:
            This type of plugin can customize response `body`, `header`, `http_code`
            This type of plugin will interrupt the request
        """
        super(Stop, self).__init__(self.__class__.__name__)

    def filter(self, request: Request, response: Response):
        """
        The plugin executes the main function
        :param request:
            request parameters and information
        :param response:
            response parameters and information
        :return:
        """
        # 在插件中可以通过 `self.config` 获取配置信息,如果插件配置为JSON将自动转换为字典结构
        # print(self.config)

        # 设置响应头信息
        headers = request.headers
        headers["X-Resp-A6-Runner"] = "Python"
        response.headers = headers

        # 设置响应体信息
        response.body = "Hello, Python Runner of APISIX"

        # 设置响应状态码
        response.status_code = 201

        # 通过调用 `self.stop()` 中断请求流程,此时将立即响应请求给客户端
        # 如果未显示调用 `self.stop()` 或 显示调用 `self.rewrite()`将继续将请求
        # 默认为 `self.rewrite()`
        self.stop()

4. 插件规范及注意事项

  • 实现插件对象必须继承 Base
  • 插件必须实现 filter 函数
  • filter 函数参数只能包含 Request Response 类对象作为参数
  • Request 对象参数可以获取请求信息
  • Response 对象参数可以设置响应信息
  • self.config 可以获取插件配置信息
  • filter 函数中调用 self.stop() 时将马上中断请求,响应数据。
  • filter 函数中调用 self.rewrite() 时,将会继续请求。

到此这篇关于Python 带你快速上手 Apache APISIX 插件开发的文章就介绍到这了,更多相关Python  Apache APISIX 插件开发内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • 最炫Python烟花代码全解析

    2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
  • python中numpy.empty()函数实例讲解

    在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
  • python-for x in range的用法(注意要点、细节)

    这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python实现b站直播自动发送弹幕功能

    这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • python Matplotlib基础--如何添加文本和标注

    这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • python 计算方位角实例(根据两点的坐标计算)

    今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • python实现双色球随机选号

    这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
  • python中使用np.delete()的实例方法

    在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
  • 使用Python的pencolor函数实现渐变色功能

    这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
  • python自动化办公操作PPT的实现

    这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
  • Python getsizeof()和getsize()区分详解

    这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20
  • jQuery Mobile开发中日期插件Mobiscroll使用说明

    这篇文章主要介绍了jQuery Mobile开发中日期插件Mobiscroll使用说明,需要的朋友可以参考下...2016-03-03
  • python实现学生通讯录管理系统

    这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • 解决python 两个时间戳相减出现结果错误的问题

    这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12