使用app dispatch技术将多个Flask应用组合成一个

动机

最近我们机器人后台系统承接的业务越来越多,除了机器人本身的后台,还有门禁系统、广告系统等的后台,都需要单独的登录流程(门禁还细分PC端小区物业登录和app端业主登录),但是我发现flask-login跟Flask app是一一对应关系,即一个app内只可能存在一个login manager,所以为了运行多个login manager,只能运行多个app

app dispatch技术

Application Dispatching是WSGI工具箱werkzeug提供的一种技术,目的是将多个Flask应用按URL前缀组合成一个应用

class DispatcherMiddleware(__builtin__.object)
 |  Allows one to mount middlewares or applications in a WSGI application.
 |  This is useful if you want to combine multiple WSGI applications::
 |  
 |      app = DispatcherMiddleware(app, {
 |          '/app2':        app2,
 |          '/app3':        app3
 |      })

实现

官方文档的示例不完整,而且就两级嵌套,不符合我们3级业务的需求(机器人登录/门禁登录/门禁管理员登录),所以决定自己实现一下

目录结构

nest
├── test_app_dispatch.py
├── ad
│   └── __init__.py
└── yeelink
    ├── __init__.py
    └── admin
        └── __init__.py

每一层组合,或者说嵌套,其模式是一模一样的,类似递归/分形,所以我只把nest跟yeelink/ad的组合代码贴出来
nest/test_app_dispatch.py内容

#encoding = utf-8

from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from flask import Flask
from yeelink import app as app_yeelink
from ad import app as app_ad

app = Flask(__name__)
app.secret_key = 'topLevel'

@app.route('/')
def index():
    return 'Hello top level!'

app = DispatcherMiddleware(app,{
    '/yeelink':     app_yeelink,
    '/ad':     app_ad
})

if __name__ == '__main__':
    run_simple('localhost', 5000, app,
               use_reloader=True, use_debugger=True, use_evalex=True)

nest/yeelink/__init__.py

#encoding = utf-8

from werkzeug.wsgi import DispatcherMiddleware
from flask import Flask,current_app,request,redirect,session,flash,url_for
from admin import app as app_admin

app = Flask(__name__)
app.secret_key = 'yeelink'

@app.route('/')
def index():
    return 'yeelink Page'

app = DispatcherMiddleware(app,{
    '/admin':     app_admin
})  

注意

DispatcherMiddleware实例不是Flask实例,没有route装饰器,所以该类的调用一定要放到所有@app.route语句的后面,否则会报以下错误:

Traceback (most recent call last):
  File "test_app_dispatch.py", line 17, in <module>
    @app.route('/')
AttributeError: 'DispatcherMiddleware' object has no attribute 'route'

因为顶层wsgi对象在import所有模块时,是按顺序执行模块语句的,所以当import执行到app.route时,app绑定的仍是Flask实例,但是执行DispatcherMiddleware后,app绑定的已经是DispatcherMiddleware实例了,最终由run_simple()方法运行该组合后的实例。

总结

app dispatch技术实现了app的隔离(独立的login managersecret_key等),同时让每层业务系统都能模块化(只关心自己的URL部分),很有用。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值