标签:实现 multi app1 完成 self 解析 __init__ art com
引言:
flask中的多实例其实和django的多app很像,不过django的多app通过二级路由分发,flask的多app是通过 DispatcherMiddleware 来实现
代码:
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from flask import Flask,current_app
app1=Flask(‘app01‘)
app2 = Flask(‘app02‘)
@app1.route(‘/hello1‘)
def hello_world1():
return ‘Hello World111!‘
@app2.route(‘/hello2‘)
def hello_world2():
return ‘Hello World222!‘
# app1这样写 不用加任何前缀 但是如果带了前缀 必须带前缀 访问app2
app = DispatcherMiddleware(app1, {
‘/app02‘: app2
})
if __name__ == ‘__main__‘:
# run_simple 第三个参数 进来执行__call__
run_simple(‘127.0.0.1‘,5000,app)
DispatcherMiddleware源码解析
class DispatcherMiddleware(object):
"""Combine multiple applications as a single WSGI application.
Requests are dispatched to an application based on the path it is
mounted under.
:param app: The WSGI application to dispatch to if the request
doesn‘t match a mounted path.
:param mounts: Maps path prefixes to applications for dispatching.
"""
"""
app=DispatcherMiddleware(app1,{
‘/app02‘:app2
})
"""
def __init__(self, app, mounts=None):
self.app = app
self.mounts = mounts or {}
def __call__(self, environ, start_response):
# 拿到当前请求的url
script = environ.get("PATH_INFO", "")
#print("script===>",script)
path_info = ""
# 第一次 /app02/hello2 不在 不进if 判断
# 第二次 /app02 进来之后就找到对应app
while "/" in script:
if script in self.mounts:
app = self.mounts[script]
break
# 切割 script, last_item=[/app02,hello2]
script, last_item = script.rsplit("/", 1)
# path_info= ‘/hello2‘
path_info = "/%s%s" % (last_item, path_info)
else:
# while else 如果while循环正常循环完成 没有被break 打断就会执行else 否则则执行
# for else 同理
# 这里如果默认请求第一个app01 第一次 scrpit 就是/hello1
# 经过script, last_item = script.rsplit("/", 1) 之后就是hello1 走这里
app = self.mounts.get(script, self.app)
original_script_name = environ.get("SCRIPT_NAME", "")
print("original_script_name===>", original_script_name)
environ["SCRIPT_NAME"] = original_script_name + script
# 重新赋值 后续需要使用路由进行匹配视图函数
environ["PATH_INFO"] = path_info
# app加括号调用执行__call__方法 后续和但实力一样 蓝图同样可以实现 不过是多个蓝图挂载到一个实例上
return app(environ, start_response)
标签:实现 multi app1 完成 self 解析 __init__ art com
原文地址:https://www.cnblogs.com/yuan-x/p/14526504.html