1. 程式人生 > >使用app dispatch技術將多個Flask應用組合成一個

使用app dispatch技術將多個Flask應用組合成一個

動機

最近我們機器人後臺系統承接的業務越來越多,除了機器人本身的後臺,還有門禁系統、廣告系統等的後臺,都需要單獨的登入流程(門禁還細分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 managersecret_key等),同時讓每層業務系統都能模組化(只關心自己的URL部分),很有用。