使用app dispatch技術將多個Flask應用組合成一個
阿新 • • 發佈:2018-12-30
動機
最近我們機器人後臺系統承接的業務越來越多,除了機器人本身的後臺,還有門禁系統、廣告系統等的後臺,都需要單獨的登入流程(門禁還細分PC端小區物業登入和app端業主登入),但是我發現flask-login跟Flask app是一一對應關係,即一個app內只可能存在一個login manager
,所以為了執行多個login manager
,只能執行多個app
app dispatch技術
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部分),很有用。