上下文本质

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. SpringAOP简介

    AOP(Aspect Orient Programming) --- 面向切面编程 将分散在各个业务逻辑中的相同代码 通过 “横向”切割方式抽取到独立模块中 方式抽取到独立模块中;[它针对的是程序运行 ...

  2. 5028: 小Z的加油店(线段树)

    NOI2012魔幻棋盘弱化版 gcd(a,b,c,d,e)=gcd(a,b-a,c-b,d-c,e-d) 然后就可以把区间修改变成差分后的点修了. 用BIT维护原序列,线段树维护区间gcd,支持点修区 ...

  3. Codeforces VK Cup Finals #424 Div.1 C. Bamboo Partition(数论)

    题目要求符合以下条件的最大的d 化简得 注意到 最多只有2*sqrt(a[i]-1)种取值,也就是一共最多有n*sqrt(10^19)种取值,于是枚举一下d,计算出符合上上式的最大的d更新答案,然后d ...

  4. Java编程MapReduce实现WordCount

    Java编程MapReduce实现WordCount 1.编写Mapper package net.toocruel.yarn.mapreduce.wordcount; import org.apac ...

  5. [freemarker篇]03.如何处理空值

    我想说的一点,我写的东西没有那么权威,这都是我实际开发中使用的,可能缺少很多! 例如这篇要说的如何处理空值,我发现我使用的跟网上很多写的不太一样,我也没有过多的去尝试网上的那么多写法! 抱歉,我只是写 ...

  6. 消除float浮动的影响

    一. 在父元素中当前浮动元素下面添加一个空的div 添加clear属性 <div style="displya:none;clear: left;"></div& ...

  7. LightOJ 1151 - Snakes and Ladders 高斯消元+概率DP

    首先来个期望的论文,讲的非常好,里面也提到了使用线性方程组求解,尤其适用于有向图的期望问题. 算法合集之<浅析竞赛中一类数学期望问题的解决方法> http://www.lightoj.co ...

  8. 【C++ STL】Map和Multimap

    1.结构 Map和multimap将key/value pair(键值/实值 队组)当作元素,进行管理.他们根据key的排序准则将元素排序.multimap允许重复元素,map不允许. 元素要求: k ...

  9. HDU 1026 Ignatius and the Princess I (广搜)

    题目链接 Problem Description The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius ...

  10. js_实现给未来元素添加事件。

    未来元素:不是一个页面上的元素,是通过js或者通过后台直接渲染在页面上的元素,也就是说这些元素不是直接写在document中的. 1.对于未来元素,我们想直接用js或者jq操作它们是不起作用的. $( ...