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 ...
随机推荐
- Django Model 数据表
Django Model 定义语法 版本:1.7主要来源:https://docs.djangoproject.com/en/1.7/topics/db/models/ 简单用法 from djang ...
- LoadRunner中的IP欺骗
应用程序服务器和网络设备使用IP地址来识别客户端.应用程序服务器通常会对来自同一计算机的客户端信息进行高速缓存. 网络路由器尝试对原信息和目标信息进行高速缓存以优化吞吐量.如果多个用户具有相同的IP地 ...
- solr单元测试
package com.taotao.rest.solr; import java.io.IOException; import org.apache.solr.client.solrj.SolrQu ...
- 牛客326B 背单词
传送门:https://ac.nowcoder.com/acm/contest/326/B 题意:给你一个n,你需有找有多少个长度从1~n 的单词,满足最长连续元音少于A个并且最长连续辅音长度少于B. ...
- Anaconda创建python(2.7/3.6)的虚拟环境后需要添加ipykernel
今天在工作的过程中遇到这样一个问题:安装完Anaconda利用conda创建了虚拟环境,但是启动jupyter notebook之后却找不到虚拟环境中的python kernel.后来上网找到了解决办 ...
- Web Service快速入门
一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 那么它是如何做到这种跨语言,跨平台之间的调用呢? 其实它是以一个xml文件以及webservice这种服务来实现跨平台 ...
- 百度地图定位API,精度提高
我使用百度定位API DEMO上面好像就可以setCoorType("bd09ll");//百度地图坐标. 然后我找了下从其它坐标体系迁移到百度坐标. 问下: 1.那我还能不能在百 ...
- 【BZOJ4069】【APIO2015】巴厘岛的雕塑 [贪心][DP]
巴厘岛的雕塑 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description 印尼巴厘岛的公路上有许多的雕塑, ...
- Python3 学习第一天总结
一.python介绍 1.python是一门动态解释性的强类型定义语言: 简单解释一下: 定义变量不需要定义类型的为动态语言:典型的有Python和Ruby,反之定义变量需要定义类型的为静态语言:典型 ...
- JS阶段测试
JS阶段测试 一.选择题 1.表单中的数据要提交到的处理文件由表单的( c )属性指定. A. method B. name C. action D. 以上都不对 2.在CSS样式 ...