Skip to main content

用于创建强大的 Sanic 插件的多合一工具包

项目描述

构建状态 最新版本 支持的 Python 版本 执照

欢迎使用 Sanic 插件工具包。

Sanic Plugin Toolkit (SPTK) 是一个轻量级的 python 库,旨在尽可能简单地为 Sanic Async HTTP 服务器构建插件。

SPTK 提供了一个SanicPlugin python 基础对象,您的插件可以在该基础对象上构建。它设置了大多数 Sanic 插件所需的所有基本功能。

SPTK Sanic 插件的实现方式与 Sanic 蓝图类似。您可以使用便利装饰器来设置插件使用的所有路由、中间件、异常处理程序和侦听器,就像您使用蓝图一样,任何应用程序开发人员都可以导入您的插件并将其注册到他们的应用程序中。

Sanic 插件工具包不仅仅是一个类似蓝图的插件系统。它提供了一个增强的中间件系统,并管理 Context 对象。

注意:如果您需要兼容 Sanic v21.03+,请更新到 SPTK v0.90.1。

增强的中间件系统

Sanic Plugin Toolkit 中的中间件系统建立在并扩展了本机 Sanic 中间件系统。SPF 中的中间件系统不是简单地拥有两个中间件队列(“请求”和“响应”),而是使用了五个额外的队列。

  • Request-Pre:这些中间件在应用程序自己的请求中间件之前运行。

  • Request-Post:这些中间件在应用程序自己的请求中间件之后运行。

  • Response-Pre:这些中间件在应用程序自己的响应中间件之前运行。

  • Response-Post:这些中间件在应用程序自己的响应中间件之后运行。

  • 清理:这些中间件在上述所有中间件之后运行,并且在发送响应后运行,即使响应为 None 也会运行。

因此,作为插件开发人员,您可以选择是否需要在应用程序自己的中间件之前或之后执行中间件。

您还可以为每个插件的中间件分配优先级,以便更精确地控制中间件的执行顺序,尤其是在应用程序使用多个插件时。

上下文对象管理器

许多人发现 Sanic 中缺少的一个功能是上下文对象。SPF 提供了多个可用于不同目的的上下文对象。

  • 共享上下文:在 SPF 中注册的所有插件都可以访问共享的、持久的上下文对象,任何人都可以读取和写入。

  • 每个请求上下文:所有插件都可以访问任何人都可以读取和写入的共享临时上下文对象,该对象在请求开始时创建,并在请求完成时删除。

  • 每个插件上下文:所有插件都有自己的私有持久上下文对象,只有该插件可以读取和写入。

  • 每个插件每个请求的上下文:所有插件都会获得一个临时私有上下文对象,该对象在请求开始时创建,并在请求完成时删除。

安装

使用 pip 或 easy_install 安装扩展。

$ pip install -U sanic-plugin-toolkit

用法

使用 Sanic Plugin Toolkit 编写的简单插件如下所示:

# Source: my_plugin.py
from sanic_plugin_toolkit import SanicPlugin
from sanic.response import text

class MyPlugin(SanicPlugin):
    def __init__(self, *args, **kwargs):
        super(MyPlugin, self).__init__(*args, **kwargs)
        # do pre-registration plugin init here.
        # Note, context objects are not accessible here.

    def on_registered(self, context, reg, *args, **kwargs):
        # do post-registration plugin init here
        # We have access to our context and the shared context now.
        context.my_private_var = "Private variable"
        shared = context.shared
        shared.my_shared_var = "Shared variable"

my_plugin = MyPlugin()

# You don't need to add any parameters to @middleware, for default behaviour
# This is completely compatible with native Sanic middleware behaviour
@my_plugin.middleware
def my_middleware(request)
    h = request.headers
    #Do request middleware things here

#You can tune the middleware priority, and add a context param like this
#Priority must be between 0 and 9 (inclusive). 0 is highest priority, 9 the lowest.
#If you don't specify an 'attach_to' parameter, it is a 'request' middleware
@my_plugin.middleware(priority=6, with_context=True)
def my_middleware2(request, context):
    context['test1'] = "test"
    print("Hello world")

#Add attach_to='response' to make this a response middleware
@my_plugin.middleware(attach_to='response', with_context=True)
def my_middleware3(request, response, context):
    # Do response middleware here
    return response

#Add relative='pre' to make this a response middleware run _before_ the
#application's own response middleware
@my_plugin.middleware(attach_to='response', relative='pre', with_context=True)
def my_middleware4(request, response, context):
    # Do response middleware here
    return response

#Add attach_to='cleanup' to make this run even when the Response is None.
#This queue is fired _after_ response is already sent to the client.
@my_plugin.middleware(attach_to='cleanup', with_context=True)
def my_middleware5(request, context):
    # Do per-request cleanup here.
    return None

#Add your plugin routes here. You can even choose to have your context passed in to the route.
@my_plugin.route('/test_plugin', with_context=True)
def t1(request, context):
    words = context['test1']
    return text('from plugin! {}'.format(words))

应用程序开发人员可以在他们的代码中使用您的插件,如下所示:

# Source: app.py
from sanic import Sanic
from sanic_plugin_toolkit import SanicPluginRealm
from sanic.response import text
import my_plugin

app = Sanic(__name__)
realm = SanicPluginRealm(app)
assoc = realm.register_plugin(my_plugin)

# ... rest of user app here

支持使用配置文件来定义在将 SPF 添加到应用程序时要加载的插件列表。

# Source: sptk.ini
[plugins]
MyPlugin
AnotherPlugin=<s>ExampleArg,False,KWArg1=True,KWArg2=33.3</s>
# Source: app.py
app = Sanic(__name__)
app.config['SPTK_LOAD_INI'] = True
app.config['SPTK_INI_FILE'] = 'sptk.ini'
realm = SanicPluginRealm(app)

# We can get the assoc object from SPF, it is already registered
assoc = spf.get_plugin_assoc('MyPlugin')

或者,如果开发人员更喜欢使用旧方式(如 Flask 方式),他们仍然可以这样做:

# Source: app.py
from sanic import Sanic
from sanic.response import text
from my_plugin import MyPlugin

app = Sanic(__name__)
# this magically returns your previously initialized instance
# from your plugin module, if it is named `my_plugin` or `instance`.
assoc = MyPlugin(app)

# ... rest of user app here

贡献

问题、意见或改进?请在Github上创建一个问题

学分

Ashley Sommer ashleysommer @ gmail com

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

sanic-plugin-toolkit-1.2.1.tar.gz (80.2 kB 查看哈希)

已上传 source

内置分布

sanic_plugin_toolkit-1.2.1-py3-none-any.whl (33.4 kB 查看哈希

已上传 py3