Flask的请求上下文机制

准备知识

面向对象双下方法

__call__ 对象后面加括号,触发执行

为什么设计上下文这样的机制?

就是保证多线程环境下,实现线程之间的隔离.

在了解flask上下文机制之前,我们先了解下线程的数据安全.

线程安全

如上代码段,在1s内开启20个线程,执行add_num(),结果foo.num都为 19,说明线程间数据是不隔离的.

那么,如何保证线程间数据隔离呢? 有一种 threading.local 方法

Thread Local

threading.local 在多线程操作时,为每一个线程开辟一个空间来保存它的值,使得线程之间的值互不影响.

import time
from threading import Thread,local

class Foo(local):
    num = 0

foo = Foo()

def add_num(i):
    foo.num = i
    time.sleep(1)
    print(i,foo.num)

for i in range(20):
    task = Thread(target=add_num,args=(i,))
    task.start()

也可以自定义一个线程安全: 定义一个全局字典,key为当前线程的线程ID,value为具体的值

import copy
import time
from threading import Thread,get_ident

class Foo():
    num = 0

foo = Foo()

dic = {}
def add_num(i):
    dic[get_ident()] = copy.copy(foo)
    dic[get_ident()].num = i
    time.sleep(1)
    print(get_ident(),dic[get_ident()].num)

for i in range(5):
    task = Thread(target=add_num,args=(i,))
    task.start()

自定义线程安全示例

Flask的上下文机制就是基于Werkzeug 的 Local Stack 实现的. 而Local Stack又依赖于local类.

Flask的请求上下文机制

先启动一个flask项目,会执行app.run()方法,这是整个项目的入口,执行run方法,里面封装了werkzeug模块中的run_simple.

from flask import Flask

app = Flask(__name__)

app.run()

 

我们用 werkzeug 来实现一个请求和响应:

from werkzeug.serving import run_simple
from werkzeug.wrappers import Request,Response

@Request.application
def app(req):
    print(req)
    return Response("200 OK!")

run_simple("127.0.0.1", 5000, app)

run_simple最终就是执行 app函数,即 app(), 那么在flask中,

run_simple中的 self 就是Flask对象,所以执行 run_simple 就触发了Flask的__call__方法.

请求上文

触发执行__call__方法,__call__方法的逻辑很简单,直接执行wsgi_app方法,将原始请求数据和一个响应函数传进去。

原文地址:https://www.cnblogs.com/yaraning/p/10572406.html

时间: 2024-08-10 09:14:24

Flask的请求上下文机制的相关文章

flask基础之AppContext应用上下文和RequestContext请求上下文(六)

前言 应用上下文和请求上下文存在的目的,官方文档讲的很清楚,可参考: http://www.pythondoc.com/flask/appcontext.html 应用上下文对象在没有请求的时候是可以单独存在的,但是请求上下文对象只有在收到请求后才会被创建.请求处理和应用上下文和请求上下文的关系是: 接收请求-->创建请求上下文-->请求上下文入栈-->创建该请求的应用上下文-->应用上下文入栈-->处理逻辑-->请求上下文出栈-->应用上下文出栈 系列文章 fl

flask 请求上下文源码(转)

本篇阅读目录 一.flask请求上下文源码解读 二.http聊天室(单聊/群聊)- 基于gevent-websocket 回到顶部 转:https://www.cnblogs.com/li-li/p/10252058.html#main 一.flask请求上下文源码解读 通过上篇源码分析,我们知道了有请求发来的时候就执行了app(Flask的实例化对象)的__call__方法,而__call__方法返回了app的wsgi_app(environ, start_response)方法的执行结果,而

Flask框架详细上下文管理机制

原创gao.xiangyang 最后发布于2018-12-12 14:20:14 阅读数 1199 收藏展开文章目录Flaskflask和django的区别一.flask配置文件二.路由系统自定义正则路由三.蓝图创建蓝图自定义蓝图的static文件夹和trmplates文件夹为某一个蓝图内所有URL路由访问地址加前缀before_request--访问URL先触发四.子域名一般固定子域名通配符子域*五. threading.local--(和flask没有关系)* 六.请求上下文管理(源码剖析)

Flask Web Development - Flask 模板1 - 模板机制&Jinja2引擎

节选自PartI Chapter3,这个chapter主要讲模板工作原理,这里讲的就是Jinja2这个模板,另外还提到了Flask-Bootstrap及Flask-Moment两个插件,前者对Flask使用Bootstrap做了些封装,后者对moment.js做了些封装.内容较多,估计分开搞. 模板存在的意义 可维护性高的代码是结构良好且整洁的. 当用户在网站注册一个账户时,他在表单里填入邮箱跟密码,并点击提交按钮.在server端就收到一个包含这些数据的request,再由Flask分发到相应

2.5.1、程序和请求上下文

Flask 从客户端收到请求时,要让视图函数能访问一些对象,这样才能处理请求.请求对象就是一个很好的例子,它封装了客户端发送的 HTTP 请求. 要想让视图函数能够访问请求对象,一个显而易见的方式是将其作为参数传入视图函数,不过这会导致程序中的每个视图函数都增加一个参数. 除了访问请求对象,如果视图函数在处理请求时还要访问其他对象,情况会变得更糟. 为了避免大量可有可无的参数把视图函数弄得一团糟,Flask 使用上下文临时把某些对象变为全局可访问.有了上下文,就可以写出下面的视图函数: from

flask-本地线程-请求上下文补充

context(上下文)是flask里面非常好的设计,使用flask需要非常理解应用上下文和请求上下文这两个概念 本地线程 本地线程(thread local)希望不同的线程对于内容的修改只在线程内部发挥作用,线程内部互相不影响 from django.test import TestCase import threading mydata = threading.local() mydata.number = 42 print(mydata.number) logs = [] def f():

应用上下文和请求上下文

from flask import Flask,request,session,url_for,current_app from werkzeug.local import Local,LocalStack #线程隔离技术 #只要绑定在Local对象上的属性 #在每个线程中都是隔离 app = Flask(__name__) # print(current_app.name)#RuntimeError: Working outside of application context. #怎么解决上

Flask 框架中 上下文基础理念,包括cookie,session存储方法,requset属性,current_app模块和g模块

Flask中上下文,分为请求上下文和应用上下文.既状态留存 ,就是把变量存在某一个地方可以调用 请求上下文:实际就是request和session用法理念,既都是可以存储东西. 应用上下文:既变量共享,就是把东西存储在变量里可以打印预览,应用上下文包括 current_app模块和g模块 cookie方法增,查,删. 注:存储cookie时使用set_coooki方法存储key--calve形式数据,另一个参数max_age 是指定的存活时间. 调用cookie的方法是通过request模块的c

解决WCF“这可能是由于服务终结点绑定未使用 HTTP 协议造成的,这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致”异常

最近对系统的架构进行优化,用WinForm模拟客户端调用WCF,在WCF起一个Bus,把接收到的消息推送到各个Sub端. 本来很简单的调用关系,结果把WCF服务部署到IIS后,一直报"接收对 http://lenovo-y460:8099/Service.svc 的 HTTP 响应时发生错误.这可能是由于服务终结点绑定未使用 HTTP 协议造成的.这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致.有关详细信息,请参见服务器日志."异常,效果如下图所示: 出异常了