f'lask源码
上下文本质
|
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,requestapp = 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源码的更多相关文章
- RDD.scala(源码)
---- map. --- flatMap.fliter.distinct.repartition.coalesce.sample.randomSplit.randomSampleWithRange. ...
- LinkedList 基本示例及源码解析
目录 一.JavaDoc 简介 二.LinkedList 继承接口和实现类介绍 三.LinkedList 基本方法介绍 四.LinkedList 基本方法使用 五.LinkedList 内部结构以及基 ...
- 源码分析:Exchanger之数据交换器
简介 Exchanger是Java5 开始引入的一个类,它允许两个线程之间交换持有的数据.当Exchanger在一个线程中调用exchange方法之后,会阻塞等待另一个线程调用同样的exchange方 ...
- 2017年中国大学生程序设计竞赛-中南地区赛暨第八届湘潭市大学生计算机程序设计大赛题解&源码(A.高斯消元,D,模拟,E,前缀和,F,LCS,H,Prim算法,I,胡搞,J,树状数组)
A------------------------------------------------------------------------------------ 题目链接:http://20 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 一篇文章看懂TPCx-BB(大数据基准测试工具)源码
TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...
- OpenCV人脸识别LBPH算法源码分析
1 背景及理论基础 人脸识别是指将一个需要识别的人脸和人脸库中的某个人脸对应起来(类似于指纹识别),目的是完成识别功能,该术语需要和人脸检测进行区分,人脸检测是在一张图片中把人脸定位出来,完成的是搜寻 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
随机推荐
- Codeforces VK Cup Finals #424 Div.1 C. Bamboo Partition(数论)
题目要求符合以下条件的最大的d 化简得 注意到 最多只有2*sqrt(a[i]-1)种取值,也就是一共最多有n*sqrt(10^19)种取值,于是枚举一下d,计算出符合上上式的最大的d更新答案,然后d ...
- bzoj1025: [SCOI2009]游戏(DP)
题目大意:将长度为n的排列作为1,2,3,...,n的置换,有可能置换x次之后,序列又回到了1,2,3,...,n,求所有可能的x的个数. 看见这种一脸懵逼的题第一要务当然是简化题意...我们可以发现 ...
- idea导入web项目tomcat
概述 主要分为项目配置和tomcat配置两大步骤. 一.项目配置 打开idea,选择导入项 选择将要打开的项目路径后,继续选择项目的原本类型(后续引导设置会根据原本的项目类型更新成idea的项目),此 ...
- pg_basebackup: invalid tar block header size
问题: 在使用pg_basebackup搭建备节点时,由于pg_basebackup本身使用的是int整型来保存传输的数据大小,当传输的数据大于4G的话,整数就会溢出,进而报出:pg_baseback ...
- POJ 2226 Muddy Fields(二分匹配 巧妙的建图)
Description Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R ...
- [解决] Error Code: 1044. Access denied for user 'root'@'%' to database
今天在测试集群用的mysql上,遇到个权限的问题: SQLException : SQL state: 42000 com.mysql.jdbc.exceptions.jdbc4.MySQLSynta ...
- 从samsung提供内核进行移植
1.尝试编译分析结果 配置编译下载尝试 (1)检查Makefile中ARCH和CROSS_COMPILE(2)make xx_defconfig(3)make menuconfig(4)make -j ...
- 南阳ACM 题目275:队花的烦恼一 Java版
队花的烦恼一 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 ACM队的队花C小+经常抱怨:"C语言中的格式输出中有十六.十.八进制输出,然而却没有二进制输出, ...
- MySQL和Postgresql的区别
一.PostgreSQL相对于MySQL的优势 1.在SQL的标准实现上要比MySQL完善,而且功能实现比较严谨:2.存储过程的功能支持要比MySQL好,具备本地缓存执行计划的能力:3.对表连接支持较 ...
- git高级用法
1.git未保存的代码怎么切换分支? 2.两个分支的代码怎么合并?怎么解决冲突? 常见报错: 1.Merge failed : Some unreacked working tree files wo ...