Flask的多app应用,多线程如何体现
一、多app应用
在一个py文件中创建多个Flask的app对象

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('/index')
def index():
return "app01" @app2.route('/index2')
def index2():
return "app2" # app1匹配路由时不需要前缀,app2匹配路由时要加上/sec前缀
dm = DispatcherMiddleware(app1, {
'/sec': app2,
})
# 得到的这个dm对象没有run方法
# 所以要用run_simple if __name__ == "__main__":
app2.__call__
run_simple('localhost', 5000, dm)

多app应用下的上下文管理,run_simple执行后当请求来时就会执行对象+括号,也就是对象的__call__方法
也就是DispatcherMiddleware的__call__方法,和单app的上下文管理是一样的,只不过多了一个筛选app的操作

class DispatcherMiddleware(object): def __init__(self, app, mounts=None):
# dm = DispatcherMiddleware(
# app1,
# { '/sec': app2,})
# 所以app就是app1,mounts就是{ '/sec': app2,}
self.app = app
self.mounts = mounts or {} def __call__(self, environ, start_response):
# 得到当前请求对应的url,比如、/sec/index
# 第二种情况,app1对应的url,比如/index没有前缀
# 那么while只循环一次就推出了
script = environ.get('PATH_INFO', '')
path_info = ''
# 循环判断/是否在url中
# 第二次循环script就变成/sec了
while '/' in script:
# 第一次进来时这个条件不成立,mounts={"/sec":app2}
# 第二次进来时条件成立
if script in self.mounts:
# 获取到的app就是app2
app = self.mounts[script]
break
# 将url按/右分割,得到script是/sec,last_item是index
script, last_item = script.rsplit('/', 1)
# 拼接url,得到path_info就是/index
path_info = '/%s%s' % (last_item, path_info)
else:
# while循环结束后依照字典中对应的url前缀取出app2
# 第二种情况while循环结束后,字典中没有对应的url前缀,所以就用默认值self.app就是app1
app = self.mounts.get(script, self.app)
original_script_name = environ.get('SCRIPT_NAME', '')
environ['SCRIPT_NAME'] = original_script_name + script
environ['PATH_INFO'] = path_info
# app即是app2,加括号,执行对象的__call__方法,也就是Flask的__call__方法,从这里开始就是我们熟悉的了
# 第二种情况url没有前缀这里的app就是app1
return app(environ, start_response)

Flask中如何提现多线程:就是Local类中的字典,是以线程的唯一标识作为key的
flask的local中保存数据时,使用列表创建出来的栈。为什么用栈?
- 如果写web程序,web运行环境;栈中永远保存1条数据(可以不用栈)。
- 写脚本获取app信息时,可能存在app上下文嵌套关系,但是pop的时候是不会出错的,因为始终都是pop最近append进去的对象

from flask import Flask, current_app, globals, _app_ctx_stack app1 = Flask('app01')
app1.debug = False # 用户/密码/邮箱 app2 = Flask('app02')
app2.debug = True # 用户/密码/邮箱
# 这样嵌套的app,stack属性列表中就不会只有一个值了,
with app1.app_context(): # __enter__方法 -> push -> app_ctx添加到_app_ctx_stack.local
# {<greenlet.greenlet object at 0x00000000036E2340>: {'stack': [<flask.ctx.AppContext object at 0x00000000037CA438>]}}
print(_app_ctx_stack._local.__storage__)
print(current_app.config['DEBUG']) with app2.app_context():
# {<greenlet.greenlet object at 0x00000000036E2340>: {'stack': [<flask.ctx.AppContext object at 0x00000000037CA438> ]}}
print(_app_ctx_stack._local.__storage__)
print(current_app.config['DEBUG']) print(current_app.config['DEBUG'])

Flask的多app应用,多线程如何体现的更多相关文章
- Flask中多APP应用以及admin后台系统
一.多APP from werkzeug.wsgi import DispatcherMiddleware from werkzeug.serving import run_simple from f ...
- Flask - flask-script | 多app应用 | wtforms
flask-script 用于实现类似于django中 python3 manage.py runserver ...类似的命令 安装 >: pip3 install flask-script ...
- 【flask】flask项目配置 app.config
[理论] 在很多情况下,你需要设置程序的某些行为,这时你就需要使用配置变量.在Flask中,配置变量就是一些大写形式的Python变量, 你也可以称之为配置参数或配置键.使用统一的配置变量可以避免在程 ...
- flask基础之app初始化(四)
前言 flask的核心对象是Flask,它定义了flask框架对于http请求的整个处理逻辑.随着服务器被启动,app被创建并初始化,那么具体的过程是这样的呢? 系列文章 flask基础之安装和使用入 ...
- Python Flask 在Sina App Engine (SAE)上安家
早就听说了Python的大名,随着的编程语言的理解加深,越发认为动态语言的威力--真大呀. 趁这段时间不忙,我也用Python写了一个应用,而且将其部署到Sina App Engine (SAE).S ...
- 六十八:flask上下文之app上下文和request上下文
app上下文: 先看现象 current_app源码 手动入栈 app_context()源码 with语句入栈 request上下文 不在app上下文中 即使手动入栈也会报错,不在请求上下文中 ur ...
- Flask—核心对象app初步理解
前言 flask的核心对象是Flask,它定义了flask框架对于http请求的整个处理逻辑.随着服务器被启动,app被创建并初始化,那么具体的过程是这样的呢? flask的核心程序就两个: 1.we ...
- flask多个app应用组合
由于之前写得接口太多了,分为了多个app,每个app里面有几个接口.部署次数需要很多次,修改成部署一次,在不改变代码的情况下,不使用蓝图,最快的方式就是这样修改. from werkzeug.wsgi ...
- Flask小总结+实例化Flask参数以及对app的配置
Flask 小而精 三方组件全 稳定性相对较差 1.启动: from flask import Flask app = Flask(__name__) app.run("0.0.0.0&qu ...
随机推荐
- 创建Tensor
目录 创建Tensor numpy, list numpy list zeros, ones, fill zeros ones fill random 打乱idx后,a和b的索引不变 constant ...
- Python中的列表(4)
1.遍历列表 如果想打印列表中的所有元素,则必须遍历列表. 可以使用for ... in ... 语句来遍历列表中的元素.遍历的意思 words = ['a','b','c','d'] for wor ...
- Jmeter关联,正则表达式提取器使用1
Jmeter关联,正则表达式提取器使用 一.Jmeter关联的方式: Jmeter中关联可以在需要获取数据的请求上 右键-->后置处理器 选择需要的关联方式,如下图有很多种方法可以提取动态 ...
- 博客搬迁至Gitcafe
原先的Github pages貌似在国内被墙了,导致搜索引擎一直没有索引到,今天一怒之下迁到Gitcafe 虽然之前的模板用不成,害我重新找了一套,改了好半天,不过总算弄完了
- 593. Valid Square
Problem statement: Given the coordinates of four points in 2D space, return whether the four points ...
- bzoj 3224 NOI2004郁闷的出纳员
NOI2004郁闷的出纳员 2013年12月26日6,1818 输入描述 Input Description 第一行有两个非负整数n和min.n表示下面有多少条命令,min表示工资下界. 接下来的n行 ...
- [NOIP2007] 提高组 洛谷P1099 树网的核
题目描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并 ...
- 网易2018校招 合唱 DP
时间限制:2秒 空间限制:131072K 小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示.对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相 ...
- BootStrap3栅格系统与布局
栅格系统与布局 Use our powerful mobile-first flexbox grid to build layouts of all shapes and sizes thanks t ...
- 2017-10-03-morning
#include <algorithm> #include <cstring> #include <cstdio> inline void read(int &am ...