上下文本质

1
2
3
4
5
6
7
8
- 当请求过来后,将请求相关数据添加到 Local()类中
    {
        线程或协程唯一标识:{"stack":[request]},
        线程或协程唯一标识:{"stack":[]},
        线程或协程唯一标识:{"stack":[]}
    }
- 以后使用时 去读取
- 请求完成之后,将request从列表中移除

Flask源码

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask,session,request
 
app = Flask(__name__)
 
@app.route("/login",methods=["GET","POST"])
def login():
    return "index"
 
if __name__ == '__main__':
    #app.__call__()
    app.run()

1. 执行app.__call__方法

def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)

2. 执行wsgi_app方法

def wsgi_app(self, environ, start_response):

    ctx = self.request_context(environ)
ctx.push() response = self.full_dispatch_request()

2.1 生成RequestContext()对象 封装请求相关的数据(request,session)

1
ctx = self.request_context(environ)
def request_context(self, environ):
return RequestContext(self, environ) class RequestContext(object):
def __init__(self, app, environ, request=None):
self.app = app
if request is None:
request = app.request_class(environ)
self.request = request

2.2 将用户请求数据封装到Local()类中

1
ctx.push()
def push(self):

    from .globals import _request_ctx_stack

    #将请求数据封装到Local()类
_request_ctx_stack.push(self) #处理session
self.session = self.app.open_session(self.request)
if self.session is None:
self.session = self.app.make_null_session()

2.2.1 导入 _request_ctx_stack对象  内部会自动生成  { 线程或协程唯一标识:{"stack":[]} } 格式

1
from .globals import _request_ctx_stack
class Local(object):

    def __init__(self):
object.__setattr__(self, '__storage__', {})
object.__setattr__(self, '__ident_func__', get_ident) def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value} class LocalStack(object): def __init__(self):
self._local = Local() def push(self, obj):
rv = getattr(self._local, 'stack', None)
if rv is None:
self._local.stack = rv = []
rv.append(obj)
return rv _request_ctx_stack = LocalStack()

2.2.2 执行_request_ctx_stack对象push方法  触发Local类的__setattr__方法 生成  { 线程或协程唯一标识:{"stack":[ RequestContext对象 ]} }

1
_request_ctx_stack.push(self)
class Local(object):

    def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value} class LocalStack(object): def push(self, obj):
"""Pushes a new item to the stack"""
rv = getattr(self._local, 'stack', None)
if rv is None:
self._local.stack = rv = [] rv.append(obj)
return rv _request_ctx_stack = LocalStack()

2.2.3 self.session重新赋值

1
2
3
4
RequestContext类的 self.session由none重新赋值为SecureCookieSessionInterface类open_session方法的结果(SecureCookieSession对象)
    - SecureCookieSession对象 就是一个字典
 
self.session = self.app.open_session(self.request)
def open_session(self, request):
return self.session_interface.open_session(self, request) # 之后这里可以自定义自己类 可以继承SecureCookieSessionInterface类
session_interface = SecureCookieSessionInterface() class SecureCookieSessionInterface(SessionInterface): def open_session(self, app, request):
s = self.get_signing_serializer(app)
if s is None:
return None # 去cookie中获取session作为key 对应的值(包含了此用户的session数据)
val = request.cookies.get(app.session_cookie_name)
if not val:
return self.session_class()
max_age = total_seconds(app.permanent_session_lifetime)
try:
data = s.loads(val, max_age=max_age)
return self.session_class(data)
except BadSignature:
return self.session_class()

3. 之后调用request

#此时你如果调用request 会执行如下代码
request = LocalProxy(partial(_lookup_req_object, 'request'))
_lookup_req_object 获取RequestContext()中用户的请求数据

4. 执行视图函数

1
response = self.full_dispatch_request()

4.1 触发只执行一次的装饰器函数 @before_first_request 

self.try_trigger_before_first_request_functions()

4.2 # 触发Flask的信号  需要pip3 install blinker

1
request_started.send(self)

4.3 执行特殊装饰器  @before_request

有返回值 返回用户
没有返回值 触发并执行视图函数
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()

4.4 执行请求之后的装饰器  @after_request  且处理session

return self.finalize_request(rv)

    def finalize_request(self, rv, from_error_handler=False):

        response = self.process_response(response)

            def process_response(self, response):

                # 处理session
if not self.session_interface.is_null_session(ctx.session):
self.save_session(ctx.session, response)

 

 

  

  

  

  

  

f'lask源码的更多相关文章

  1. RDD.scala(源码)

    ---- map. --- flatMap.fliter.distinct.repartition.coalesce.sample.randomSplit.randomSampleWithRange. ...

  2. LinkedList 基本示例及源码解析

    目录 一.JavaDoc 简介 二.LinkedList 继承接口和实现类介绍 三.LinkedList 基本方法介绍 四.LinkedList 基本方法使用 五.LinkedList 内部结构以及基 ...

  3. 源码分析:Exchanger之数据交换器

    简介 Exchanger是Java5 开始引入的一个类,它允许两个线程之间交换持有的数据.当Exchanger在一个线程中调用exchange方法之后,会阻塞等待另一个线程调用同样的exchange方 ...

  4. 2017年中国大学生程序设计竞赛-中南地区赛暨第八届湘潭市大学生计算机程序设计大赛题解&源码(A.高斯消元,D,模拟,E,前缀和,F,LCS,H,Prim算法,I,胡搞,J,树状数组)

    A------------------------------------------------------------------------------------ 题目链接:http://20 ...

  5. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  6. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  7. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  8. OpenCV人脸识别LBPH算法源码分析

    1 背景及理论基础 人脸识别是指将一个需要识别的人脸和人脸库中的某个人脸对应起来(类似于指纹识别),目的是完成识别功能,该术语需要和人脸检测进行区分,人脸检测是在一张图片中把人脸定位出来,完成的是搜寻 ...

  9. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

随机推荐

  1. 关于JavaScript的push()函数

    push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度.返回值为把指定的值添加到数组后的新长度. 语法:arrayObject.push(newelement1,newelement2,. ...

  2. Android 解决adb server is out of date. killing... ADB server didn't ACK * failed to star

    The connection to adb is down, and a severe error has occured. [-- :: - HelloOPone] You must restart ...

  3. HRBUST 1819

    石子合并问题--圆形版 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 61(27 users) Total Accepted: 26( ...

  4. 关于MyBatis一些小错误,元素内容必须由格式正确的字符数据或标记组成.

    今天在Mapper.xml文件写查询语句报了个奇怪的错误 Caused by: org.apache.ibatis.builder.BuilderException: Error creating d ...

  5. 数据结构:K-D树

    K-D树实际上是一棵高维二叉搜索树,与普通二叉搜索树不同的是,树中存储的是一些K维数据 普通的二叉搜索树是一维的,当推广到K维后,就是我们的K-D树了 在K-D树中跟二叉搜索树差不多,也是将一个K维的 ...

  6. [Luogu 2221] HAOI2012 高速公路

    [Luogu 2221] HAOI2012 高速公路 比较容易看出的线段树题目. 由于等概率,期望便转化为 子集元素和/子集个数. 每一段l..r中,子集元素和为: \(\sum w_{i}(i-l+ ...

  7. Android开发——为移动的Paint元素指定图片的方法

    源  起 最近在写一个类似“围住神经猫”的应用,现在需要给一个可以移动的Paint元素指定一张图片,如下图,要把黄点改成其他图片: Paint所在的类继承于SurfaceView,SurfaceVie ...

  8. 【BZOJ4868】期末考试 [三分][贪心]

    期末考试 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input Output Samp ...

  9. 「6月雅礼集训 2017 Day11」jump

    [题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...

  10. 【51NOD-0】1134 最长递增子序列

    [算法]动态规划 [题解]经典模型:最长上升子序列(n log n) #include<cstdio> #include<algorithm> #include<cstr ...