我正在处理一个 python 应用程序,它由多个分布式轻量级组件组成,这些组件使用 RabbitMQ 进行通信。 & Kombu .
一个组件监听两个队列并且可以在每个队列上接收多种消息类型。子类可以通过注册自定义处理程序来覆盖每种消息类型的处理方式。 所有这一切都很好。
我现在有一个额外的要求,即每个组件必须有一个基本的 REST/HTML 接口(interface)。这个想法是您将浏览器指向正在运行的组件并获取有关它当前正在做什么的实时信息(它正在处理什么消息、cpu 使用率、状态信息、日志等)
它需要轻量级,所以经过一些研究后我决定使用 Flask(但我愿意接受建议)。在伪代码中,这意味着采取:
class Component:
Queue A
Queue B
...
def setup(..):
# connect to the broker & other initialization
def start(..):
# start the event loop and wait for work
def handle_msg_on_A(self,msg):
# dispatch a msg to a handler depending on the msg type
def handle_msg_on_B(self,msg):
...
...
并添加一些 View 方法:
@app.route('/')
def web_ui(self):
# render to a template
@app.route('/state')
def get_state(self):
# REST method to return some internal state info as JSON
...
但是,将 Web UI 连接到这样的类会中断 SOLID原则并带来继承问题(子类可能希望显示更多/更少信息)。装饰器不是继承的,因此每个 View 方法都需要显式覆盖和重新装饰。也许使用 mixin + 反射可以以某种方式工作,但感觉很老套。
相反,使用组合可能会起作用:将网络内容放在一个单独的类中,该类将 url 路由委托(delegate)给嵌套组件上一组固定的、预定义的多态方法。 通过这种方式,组件会以损失一些灵 active 为代价保持对 Flask 的感知(可用方法集是固定的)。
我现在发现了Flask blueprints和 Application Dispatching看起来他们可以带来更好、更可扩展的解决方案。但是,我还没有完全理解它们。
我觉得我在这里缺少一种设计模式,希望有更多 flask-fu 或对此类问题有经验的人可以发表评论。
最佳答案
Flask 0.7 中悄悄引入了您可能感兴趣的其他内容 - Pluggable Views .这些是基于类而不是基于函数的端点 - 因此您可以使用 dispatch_request
管理状态转换的方法(仅在需要时覆盖它)。
与使用应用程序分派(dispatch)相比,这样做的好处是您可以在整个应用程序中获得 url_for
支持(而不是必须在跨应用程序边界的 URL 中进行硬编码。 ) 您必须确定这是否可能成为您的应用程序的问题。
在伪代码中:
# File: Components.py
from flask.views import View
class Component(View):
# Define your Component-specific application logic here
dispatch_request(self, *url_args, **url_kwargs):
# Define route-specific logic that all Components should have here.
# Call Component-specific methods as necessary
class Tool_1(Component):
pass
class Tool_2(Component):
# Override methods here
# File: app.py
from flask import Flask
from yourapplication import Tool_1, Tool_2
app = Flask()
# Assuming you want to pass all additional parameters as one argument
app.add_url_rule("/tool_1/<path:options>", "tool1", view_func=Tool_1.as_view())
# Assuming you want to pass additional parameters separately
tool_2_view = Tool_2.as_view()
app.add_url_rule("/tool_2/", "tool2", view_func=tool_2_view )
app.add_url_rule("/tool_2/<option>", "tool2", view_func=tool_2_view)
app.add_url_rule("/tool_2/<option>/<filter>", "tool2", view_func=tool_2_view)
如果您有一系列在逻辑上都连接在一起的组件并且您不想记住放置 /prefix
在每个人的 add_url_rule
调用之前。但是,如果您只有一系列大部分彼此独立的组件,这就是我会使用的模式*。
*。 另一方面,如果它们需要彼此隔离,我会使用文档中推荐的应用程序分派(dispatch)模式。
关于python - 将 REST 行为添加到带有 flask 的类中,蓝图的案例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7256889/