您的位置:首页 > 移动开发

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

2017-06-12 15:29 453 查看

动机

最近我们机器人后台系统承接的业务越来越多,除了机器人本身的后台,还有门禁系统、广告系统等的后台,都需要单独的登录流程(门禁还细分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 manager
secret_key
等),同时让每层业务系统都能模块化(只关心自己的URL部分),很有用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  flask-web开发