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 ...
随机推荐
- 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基
大力观察:I.从输出精准位数的约束来观察,一定会有猫腻,然后仔细想一想,就会发现输出的时候小数点后面不是.5就是没有 II.从最后答案小于2^63可以看出当k大于等于3的时候就可以直接搜索了 期望概率 ...
- Samba共享传输大文件(ex:1G)失败的问题
1:问题描述 1.1 基本信息 遇见这样一个bug,路由器有USB share的功能,可将U盘内的文件通过samba和LAN端PC机中文件进行共享,测试发现小文件可正常共享,一旦文件大了(比如1G左右 ...
- linux 命令后台运行(转载)
原文连接:https://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html 有两种方式: 1. command & : 后台运行 ...
- Sublime Text3 安装Markdown
Sublime Text3是一款给力的文本编辑器,通过安装插件可以编辑Markdown文本,在编辑Markdown文本的同时可以实时预览编辑效果. 安装准备: 找到菜单栏:Preferences → ...
- [LeetCode] 7. Reverse Integer ☆
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have y ...
- 2017 济南综合班 Day 6
循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K ...
- asyncio Lock,Queue
# # total = 0 # # async def add(): # #1. dosomething1 # #2. io操作 # # 1. dosomething3 # global total ...
- 上下文管理器 contextlib
from contextlib import contextmanager @contextmanager def tag(name): print "<%s>" % ...
- RDLC - 后台代码直接导出Excel/PDF/Word格式
最近做报表功能,用到了.net的报表组件rdlc. 其中有个功能就是后台代码直接输出Excel/PDF/Word格式的文件,网上看了些资源,做个总结: 参考地址 我直接贴出代码: //自动导出exce ...
- CPU上下文切换的次数和时间(context switch)
什么是CPU上下文切换? 现在linux是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要把当前状态保存下来,同时加载下一个任务,这个过程叫做上下文切换.时间片轮转的方式,使得 ...